5

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

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

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

4

3 回答 3

16

如果你可以确定你的 zip 文件永远不会被打包在另一个 jar 中,你可以使用类似的东西:

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

或者:

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"));

否则,您的选择是:

  • 对于需要加载的每个条目,使用 ZipInputStream 扫描 zip 文件一次。如果您有很多资源,这可能会很慢,除非您可以为所有资源重用相同的 ZipInputStream。
  • 不要将资源打包在嵌套的 zip 文件中,只需将它们与代码一起内联到 jar 中。
  • 将嵌套的 zip 文件复制到临时目录中,并使用 ZipFile 类访问它。
于 2012-11-15T14:42:16.620 回答
3

你目前的方法肯定行不通。您制定了一个任意的“访问”方案,并在一个不知道您要做什么的类中使用它。您可以做的是使用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
}

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

于 2012-11-15T14:26:47.027 回答
0

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

于 2012-11-15T14:27:39.300 回答