直接读取 Zip 文件中的文件 - Java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13399448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:34:28  来源:igfitidea点击:

Read directly a file within a Zip file - Java

javazipzipfile

提问by Adil

My situation is that I have a zip file that contains some files (txt, png, ...) and I want to read it directly by their names, I have tested the following code but no result (NullPointerExcepion):

我的情况是我有一个包含一些文件(txt、png、...)的 zip 文件,我想直接通过它们的名称读取它,我测试了以下代码但没有结果(NullPointerExcepion):

InputStream in = Main.class.getResourceAsStream("/resouces/zipfile/test.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));

resourcesis a package and zipfileis a zip file.

resources是一个包,zipfile是一个 zip 文件。

回答by Martin Ellis

If you can be sure that your zip file will never be packed inside another jar, you can use something like:

如果您可以确定您的 zip 文件永远不会被打包到另一个 jar 中,您可以使用以下内容:

URL zipUrl = Main.class.getResource("/resources/zipfile.zip");
URL entryUrl = new URL("jar:" + zipUrl + "!/test.txt");
InputStream is = entryUrl.openStream();

Or:

或者:

URL zipUrl = Main.class.getResource("/resources/zipfile.zip");
File zipFile = new File(zipUrl.toURI());
ZipFile zip = new ZipFile(zipFile);
InputStream is = zip.getInputStream(zip.getEntry("test.txt"));

Otherwise, your choices are:

否则,您的选择是:

  • Use a ZipInputStream to scan through the zip file once for each entry that you need to load. This may be slow if you have a lot of resources, unless you can reuse the same ZipInputStream for all your resources.
  • Don't pack the resources in a nested zip file, and just inline them in the jar with the code.
  • Copy the nested zip file into a temporary directory, and access it using the ZipFile class.
  • 使用 ZipInputStream 为您需要加载的每个条目扫描一次 zip 文件。如果您有很多资源,这可能会很慢,除非您可以为所有资源重用相同的 ZipInputStream。
  • 不要将资源打包在嵌套的 zip 文件中,只需将它们与代码内联到 jar 中。
  • 将嵌套的 zip 文件复制到临时目录中,然后使用 ZipFile 类访问它。

回答by Perception

Your current approach is definitely not going to work. You made up an arbitrary 'access' scheme and used it in a class that has no idea what you are trying to do. What you cando is use a ZipInputStreamto read the entry you are looking for:

你目前的方法肯定行不通。您制定了一个任意的“访问”方案,并在不知道您要做什么的班级中使用它。您可以做的是使用ZipInputStream来读取您要查找的条目:

URL zipFileURL = Thread.currentThread().getContextClassLoader().getResource("zipfile.zip");
InputStream inputStream = zipFileURL.openStream();
ZipInputStream zipInputStream = new ZipInputStream(inputStream);

ZipEntry zipEntry = null;

do {
    zipEntry = zipInputStream.getNextEntry();
    if(zipEntry == null) break;
}
while(zipEntry != null && (! "textfile".equals(zipEntry.getName()));

if(zipEntry != null ) {
    // do some stuff
}

This is adhoc code, fix it up to do what you need. Also, there might be some more efficient classes to handle Zip files, for example in the Apache Commons IO library.

这是临时代码,修复它以执行您需要的操作。此外,可能有一些更有效的类来处理 Zip 文件,例如在 Apache Commons IO 库中。

回答by muruga

What is the path of the test.txt within the zip file? You need to use the path within the zip file to read this file. Also make sure that your zipfile is in the classpath. In fact, you can bundle this in a jar file.

zip 文件中 test.txt 的路径是什么?您需要使用 zip 文件中的路径来读取此文件。还要确保您的 zipfile 在类路径中。实际上,您可以将其捆绑在一个 jar 文件中。