以前我们的Web应用程序中有一些zip文件.我们希望在zip文件中削减特定的文本文档.这不是问题:
URL url = getClass().getResource(zipfile);
ZipFile zip = new ZipFile(url.getFile().replaceAll("%20", " "));
Entry entry = zip.getEntry("file.txt");
InputStream is = zip.getInputStream(entry);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
但是我们已经将这些zip文件移动到另一个模块中,并希望将它们打包到jar中.不幸的是,创建ZipFile现在失败了.我可以获得一个InputStreamzip:但我无法获得条目本身的输入流.
InputStream is = getClass().getResourceAsStream(zipfile);
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while (entry != null && !entry.getName().equals("file.txt")) {
entry = zis.getNextEntry();
}
Run Code Online (Sandbox Code Playgroud)
但我无法获得条目本身的输入流.我尝试找到条目的长度并从中获取下一个n字节,ZipInputStream但这对我不起作用.似乎读取的所有字节都是0.
有没有办法解决这个问题,还是我必须将zip文件移回核心项目?
TrueZip怎么样?使用它,您只需打开压缩文件,就好像它位于目录中一样.
new FileOutputStream("/path/to/some-jar.jar/internal/zip/file.zip/myfile.txt");
Run Code Online (Sandbox Code Playgroud)
根据文档,还支持无限嵌套.我还没有真正使用这个项目,但它已经在我的雷达上了一段时间,它似乎适用于你的问题.
项目地点:http://truezip.java.net/(已编辑)
条目可以为您提供内部 zip 文件的输入流。
InputStream innerzipstream = zip.getInputStream(entry);
Run Code Online (Sandbox Code Playgroud)
所以你可以使用
new ZipInputStream(innerzipstream);
Run Code Online (Sandbox Code Playgroud)
并要求 ZipInputStream 检索内部 zip 文件的内容(以有序的方式,您不能随机访问,因为它是 ZipInputStream)
看看http://download.oracle.com/javase/1.4.2/docs/api/java/util/zip/ZipInputStream.html
顺序 zip 访问
由于 ZipInputStream 正在从输入流读取 zip 文件,因此它必须按顺序执行操作:
// DO THIS for each entry
ZipEntry e = zipInputStreamObj.getNextEntry();
e.getName // and all data
int size = e.getSize(); // the byte count
while (size > 0) {
size -= zipInputStreamObj.read(...);
}
zipInputStreamObj.closeEntry();
// DO THIS END
zipInputStreamObj.close();
Run Code Online (Sandbox Code Playgroud)
注意:我不知道当到达 zip 文件末尾时 ZipInputStream.getNextEntry() 是否返回 null。我希望如此,因为当没有更多条目时我不知道其他方式来实现。