先上正确方法:

  正确方式应该为,先创建一个ZipFile,然后对其entries做遍历,每一个entry其实就是一个文件或者文件夹,检测到文件夹的时候创建文件夹,其他情况创建文件,其中使用zipFile.getInputStream(entry)可以获得当前文件的输入流(注意是文件的输入流不是压缩文件的输入流)。然后把它写到writer里就可以了。嘛,明明很简单的。下面是一个例子,读取GBK格式的压缩包,压缩包中的文件编码也为GBK格式(就是在windows下写的文件并打包的情况),输出为UTF8的解压(跨平台使用)。

  def decompressZip(source: File, dest: String, sourceCharacters: String = "GBK", destCharacters: String = "UTF-8") = {
if (source.exists) {
var os: OutputStream = null
var inputStream: InputStreamReader = null
var outWriter: OutputStreamWriter = null
val zipFile = new ZipFile(source, sourceCharacters)
var entries = zipFile.getEntries entries.foreach(entry =>
if (entry.isDirectory())
new File(dest + entry.getName).mkdirs()
else if (entry != null) {
try{
val name = entry.getName
val path = dest + name
var content = new Array[Char](entry.getSize.toInt)
inputStream = new InputStreamReader(zipFile.getInputStream(entry), sourceCharacters)
println(inputStream.read(content))
val entryFile = new File(path)
checkFileParent(entryFile)
os = new FileOutputStream(entryFile)
outWriter = new OutputStreamWriter(os, destCharacters);
outWriter.write(new String(content))
} catch {
case e: Throwable => e.printStackTrace()
}finally{
if (os != null){
os.flush
os.close
}
if (outWriter != null){
outWriter.flush
outWriter.close
}
if (inputStream != null) inputStream.close
}
})
zipFile.close
}
}

  错误示范:

  不知道为什么,网上很多教程都是使用ZipArchiveInputStream来进行解压,然而:

  The ZipFile class is preferred when reading from files as ZipArchiveInputStream is limited by not being able to read the central directory header before returning entries. In particular ZipArchiveInputStream

  • may return entries that are not part of the central directory at all and shouldn't be considered part of the archive.
  • may return several entries with the same name.
  • will not return internal or external attributes.
  • may return incomplete extra field data.
  • may return unknown sizes and CRC values for entries until the next entry has been reached if the archive uses the data descriptor feature.

  在commons-compress的1.3版本就开始建议使用ZipFile了。

  我个人而言,尝试过ZipArchiveInputStream之后发现一个问题,ZipArchiveInputStream创建方式很麻烦,需要指定一个InputStream,而这个方法在API文档中是这么写的

Constructors
Constructor and Description
ZipArchiveInputStream(InputStream inputStream)

Create an instance using UTF-8 encoding
ZipArchiveInputStream(InputStream inputStream, String encoding)

Create an instance using the specified encoding
ZipArchiveInputStream(InputStream inputStream, String encoding, boolean useUnicodeExtraFields)

Create an instance using the specified encoding
ZipArchiveInputStream(InputStream inputStream, String encoding, boolean useUnicodeExtraFields, boolean allowStoredEntriesWithDataDescriptor)

Create an instance using the specified encoding

  Parameters:inputStream - the stream to wrap

  这个构造方法没有指明这个inputStream参数是什么东西,照网上的方法试了试,使用:  

val zipFile = new ZipFile(source, sourceCharacters)
var entries = zipFile.getEntries
entries.foreach(entry =>
if (entry != null) {
try{
val name = entry.getName
val path = dest + name
var content = new Array[Char](entry.getSize.toInt)
zais = new ZipArchiveInputStream(zipFile.getInputStream(entry))
val entryFile = new File(path)
checkFileParent(entryFile)
os = new FileOutputStream(entryFile)
IOUtils.copy(zais, os)
………………

  读出来的数据是空,使用zais.read读出Array[Byte]并把它转化为字符串发现是空白符字符串,直接输出Array[Byte]发现都是0。后来看文档大概知道是什么原因,这个ZipArchiveInputStream读取的应该是Zip文件,然而zipFile.geiInputStream返回的是解压完的文件的输入流,所以才会出现这个问题,试了试commons-compress spark依赖12年出的1.4版本和最新的1.14版本这种方法都是错的,所以我怀疑他们12年之后转的那些博客并没有经过自己使用和测试就转发了。这个ZipFile和ZipArchiveInputStream混用总觉得怪怪的。。。

使用commons-compress解压GBK格式winzip文件到UTF8,以及错误使用ZipArchiveInputStream读出来数据全是空的解决办法的更多相关文章

  1. JAVA解压.Z及.ZIP文件

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --> <dependency ...

  2. 文件压缩、解压工具类。文件压缩格式为zip

    package com.JUtils.file; import java.io.BufferedOutputStream; import java.io.File; import java.io.Fi ...

  3. 解压gzip格式文件(包括网页)

    先上源码 参数说名: - source :gzip格式流内容. - len: gzip流长度 - dest: 解压后字符流指针 - gzip: 压缩标志,非0时解压gzip格式,否则按照zip解压 说 ...

  4. C#使用Expand、Shell32解压Cab、XSN文件

    前言: 需要解压InfoPath表单的xsn文件,在项目中以前使用的是Expand命令行解压,都没有出过问题,近段时间项目中突然报错解压失败,通过分析解压操作得出结论: 1.正常正常情况下,expan ...

  5. tar 解压某个指定的文件或者文件夹

    1. 先查看压缩文档中有那些文件,如果都不清楚文件内容,然后就直接解压,这个是不可能的 使用#tar -tf 压缩包名称,可以查看压缩包内容 2.解压某个文件 tar -zxvf zabbix.tar ...

  6. 如何解压POSIX tar archive文件

    下载了一个xxx.gz的文件,使用x xxx.gz(zsh的x插件,十分之好用,再也不用担心tar后面该加哪些参数了)的命令解压,然后出现了一个文件,本以为解压后是一个文件夹:然后一脸蒙逼~ 突然又想 ...

  7. 解压.zip,.tar.gz文件到指定目录,重命名文件

    1.解压文件到指定目录 /** * 解压文件到指定目录 * zipFile:要解压的文件 * descDir:解压到哪个文件 * */ @SuppressWarnings("rawtypes ...

  8. tar解压某个目录 tar解压某个指定的文件或者文件夹

    tar解压某个目录 tar解压某个指定的文件或者文件夹 发布时间:2017-05-30 来源:服务器之家   1. 先查看压缩文档中有那些文件,如果都不清楚文件内容,然后就直接解压,这个是不可能的 使 ...

  9. Python:将utf-8格式的文件转换成gbk格式的文件

    需求:将utf-8格式的文件转换成gbk格式的文件 实现代码如下: def ReadFile(filePath,encoding="utf-8"): with codecs.ope ...

随机推荐

  1. JavaScript字符串String

    JavaScript中String类型用于表示由零个或者多个16位Unicode字符组成的字符序列即字符串:同时字符串可以用单引号或双引号表示. 下面是一些特殊的字面量: 字面量 含义\n 换行\t ...

  2. webpack导入css及各项loader

    1. webpack导入css 1) 下载相关的加载器 npm install style-loader css-loader -D 2)将index.css引入到mian.js中 import '. ...

  3. LATCH_EX

    Description: This wait type occurs when a thread is waiting for access to a non-page data structure ...

  4. C# install-package:"xx"已拥有为“xxx”定义的依赖项

    可能 nuget自身的版本落后于适配程序包的版本 Visual Studio 2013 更新 NuGet 包管理器 Ø  前言 使用 Visual Studio 中的 NuGet 包管理器下载程序时, ...

  5. HP1020打印机“传递给系统调用的数据区域太小” 如何处理?

    如果电脑上曾经安装过 HP LaserJet 激光打印机的驱动程序,重新安装驱动程序之前,需要完全卸载以前安装的驱动程序,否则可能会出现无法找到设备或者安装不上驱动程序的现象. 安装网站下载的即插即用 ...

  6. Redis入门到高可用(八)——list

    一.结构 key - value 结构,value是一个有序队列. 可进行左边的添加及弹出,右边的添加及弹出. 可获取列表的长度,删除列表中指定元素,获取列表的子列表,按照索引获取列表的指定元素. 特 ...

  7. VS中属性配置ABC

    1.包含目录和附加包含目录(库目录和附加库目录)的区别: 包含目录:修改了系统的include宏的值,是全局的: 附加包含目录:用于当前项目,对其他项目没有影响. (库目录和附加库目录的区别同上) 2 ...

  8. mybatis级联

    mybatis中有时候表不能都分成单表进行查询,表之间会有联系,这时候需要将表进行级联 下面讲一下如何将mybatis中 的表进行级联.映射表关系如下 1:创建数据表 DROP TABLE IF EX ...

  9. DLNg序列模型第二周NLP与词嵌入

    1.使用词嵌入 给了一个命名实体识别的例子,如果两句分别是“orange farmer”和“apple farmer”,由于两种都是比较常见的,那么可以判断主语为人名. 但是如果是榴莲种植员可能就无法 ...

  10. 2018-2019-1 20189221 《Linux内核原理与分析》第六周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第六周作业 实验五 实验过程 将Fork函数移植到Linux的MenuOS fork()函数通过系统调用创建一个与原来 ...