先上正确方法:

  正确方式应该为,先创建一个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. es定制排序搜索结果

    GET /company/employee/_search { "query": { "constant_score": { "filter" ...

  2. MTU 和 MSS 关系、 IP分片、TCP分段

    从四层模型:链路层,网络层,传输层,应用层说 一 .以太网V2格式数据帧 : 链路层 Destination   Source  Type  DataAndPad  FCS 6            ...

  3. Docker 引擎(三)

    Docker 引擎是一个包含以下主要组件的客户端服务器应用程序. 一种服务器,它是一种称为守护进程并且长时间运行的程序. REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么. 一 ...

  4. VS Code 添加移除asp.net core项目引用

    可以通过编辑.csproj文件来添加或者移除项目引用. 注意这里并没有智能提示, 最好是在Nuget网站(https://www.nuget.org/)搜索好相关包之后填写进来. 编辑结束之后, vs ...

  5. [django]drf知识点梳理-权限

    用户 - 权限 - 资源 (拥有) (绑定) django权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮 django权限控制 Djan ...

  6. 【Java】-NO.16.EBook.4.Java.1.010-【疯狂Java讲义第3版 李刚】- 异常

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.010-[疯狂Java讲义第3版 李刚]- 异常 Style:EBook Series:Java Si ...

  7. 解决bug感觉

    解决bug,没有思路,很烦躁: 时间过去好久,还是没头绪,没结论: ...... ...... ...... ...... ...... 过了好久,这样还不如冷静下来,按照正确的方法(review代码 ...

  8. 23个适合logo设计的常用英文字体

    在很多国外的品牌中我们都会发现他们的英文字体在logo的运用中,不仅会提升logo的品质还会让logo看起来更加美观.今天我们就来看看都有哪些常常出现在logo设计中的英文字体吧.   字体,与文字本 ...

  9. RNN/LSTM/GRU/seq2seq公式推导

    概括:RNN 适用于处理序列数据用于预测,但却受到短时记忆的制约.LSTM 和 GRU 采用门结构来克服短时记忆的影响.门结构可以调节流经序列链的信息流.LSTM 和 GRU 被广泛地应用到语音识别. ...

  10. [文摘]那些一心想要离开 BAT 的人,后来怎么样了?

    人心是个无底洞,填不满也掏不空 <Working at Google seemed like a dream job. The reality has been a tedious, point ...