【发布时间】:2010-01-14 09:05:06
【问题描述】:
我正在尝试编写一个函数,该函数将接受带有压缩文件数据的InputStream,并返回另一个带有解压缩数据的InputStream。
压缩后的文件将只包含一个文件,因此不需要创建目录等...
我尝试查看 ZipInputStream 和其他人,但我对 Java 中如此多不同类型的流感到困惑。
【问题讨论】:
-
你已经尝试了什么?请添加一些代码示例。
我正在尝试编写一个函数,该函数将接受带有压缩文件数据的InputStream,并返回另一个带有解压缩数据的InputStream。
压缩后的文件将只包含一个文件,因此不需要创建目录等...
我尝试查看 ZipInputStream 和其他人,但我对 Java 中如此多不同类型的流感到困惑。
【问题讨论】:
概念
GZIPInputStream 用于压缩为 gzip(“.gz”扩展名)的流(或文件)。它没有任何标题信息。
该类实现了一个流过滤器,用于读取 GZIP 文件格式的压缩数据
如果你有一个真正的 zip 文件,你必须使用 ZipFile 打开文件,询问文件列表(在你的例子中是一个)并询问解压缩的输入流。
如果您有文件,您的方法将类似于:
// ITS PSEUDOCODE!!
private InputStream extractOnlyFile(String path) {
ZipFile zf = new ZipFile(path);
Enumeration e = zf.entries();
ZipEntry entry = (ZipEntry) e.nextElement(); // your only file
return zf.getInputStream(entry);
}
读取带有 .zip 文件内容的 InputStream
好的,如果你有一个 InputStream,你可以使用(正如@cletus 所说)ZipInputStream。它读取包含标头数据的流。
ZipInputStream 用于带有 [header information + zippeddata] 的流
重要提示:如果您的 PC 中有文件,您可以使用 ZipFile 类随机访问它
这是通过 InputStream 读取 zip 文件的示例:
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Main {
public static void main(String[] args) throws Exception
{
FileInputStream fis = new FileInputStream("c:/inas400.zip");
// this is where you start, with an InputStream containing the bytes from the zip file
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry entry;
// while there are entries I process them
while ((entry = zis.getNextEntry()) != null)
{
System.out.println("entry: " + entry.getName() + ", " + entry.getSize());
// consume all the data from this entry
while (zis.available() > 0)
zis.read();
// I could close the entry, but getNextEntry does it automatically
// zis.closeEntry()
}
}
}
【讨论】:
zis.read() 时,数据去哪儿了?我的 zip 文件将只包含一个文件,我只想返回一个未压缩的文件数据流。
如果您可以更改输入数据,我建议您使用GZIPInputStream。
GZipInputStream 与 ZipInputStream 不同,因为其中只有一个数据。所以整个输入流代表整个文件。在ZipInputStream 中,整个流还包含其中文件的结构,可以有很多。
【讨论】:
它是 scala 语法:
def unzipByteArray(input: Array[Byte]): String = {
val zipInputStream = new ZipInputStream(new ByteArrayInputStream(input))
val entry = zipInputStream.getNextEntry
IOUtils.toString(zipInputStream, StandardCharsets.UTF_8)
}
【讨论】:
除非我遗漏了什么,否则您绝对应该尝试让ZipInputStream 工作,而且没有理由不应该这样做(我当然曾多次使用它)。
你应该做的是尝试让ZipInputStream 工作,如果你不能,发布代码,我们会帮助你解决你遇到的任何问题。
不过,无论您做什么,都不要尝试重新发明它的功能。
【讨论】:
java.util.zip 是一个非常令人不快的 API
ZipFile.unzip(destDir) 方法,对吧?或者一种通过名称/模式轻松查找条目的方法。这个 API 太恶心了。