使用InputStreamReader读取JAR中的目录

所以,这个问题已被问过我相信的一百万次,而且我已经读了几个小时,尝试了一些人给出的几种选择,但没有一种适合我。

我想在应用程序的JAR中列出目录中的所有文件,因此在IDE中这有效:

File f = new File(this.getClass().getResource("/resources/").getPath()); for(String s : f.list){ System.out.println(s); } 

这给了我目录中的所有文件。

现在,我也试过这个:

 InputStream in = this.getClass().getClassLoader().getResourceAsStream("resources/"); InputStreamReader inReader = new InputStreamReader(in); Scanner scan = new Scanner(inReader); while (scan.hasNext()) { String s = scan.next(); System.out.println("read: " + s); } System.out.println("END OF LINE"); 

从IDE中打印出目录中的所有文件。 外部IDE打印:“END OF LINE”。

现在,我也可以在Jar中找到一个条目:

  String s = new File(this.getClass().getResource("").getPath()).getParent().replaceAll("(!|file:\\\\)", ""); JarFile jar = new JarFile(s); JarEntry entry = jar.getJarEntry("resources"); if (entry != null){ System.out.println("EXISTS"); System.out.println(entry.getSize()); } 

那是我必须对那个String做的一些可怕的编码。

无论如何……我无法获得Jar内“resources”目录中的资源列表……我该怎么办?

在没有首先枚举Jar文件的内容的情况下,无法简单地获取内部资源的过滤列表。

幸运的是,这实际上并不那么难(幸运的是,你已经完成了大部分的努力工作)。

基本上,一旦你有了对JarFile的引用,你就需要简单地询问它的’ entries并迭代该列表。

通过检查所需匹配的JarEntry名称(即resources ),您可以过滤所需的元素…

例如…

 import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class ReadMyResources { public static void main(String[] args) { new ReadMyResources(); } public ReadMyResources() { JarFile jf = null; try { String s = new File(this.getClass().getResource("").getPath()).getParent().replaceAll("(!|file:\\\\)", ""); jf = new JarFile(s); Enumeration entries = jf.entries(); while (entries.hasMoreElements()) { JarEntry je = entries.nextElement(); if (je.getName().startsWith("resources")) { System.out.println(je.getName()); } } } catch (IOException ex) { ex.printStackTrace(); } finally { try { jf.close(); } catch (Exception e) { } } } } 

警告

这类问题实际上有点问题。 而不是尝试在运行时读取Jar的内容,最好生成某种包含可用资源列表的文本文件。

这可以由您的构建过程在创建Jar文件之前动态生成。 这将是一个更简单的解决方案然后读取此文件(例如通过getClass().getResource() )然后查找文本文件中的每个资源列表…恕我直言

对于Spring Framework用户,请查看PathMatchingResourcePatternResolver以执行以下操作:

 PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("classpath:path/to/resource/*.*"); for (Resource resource : resources) { InputStream inStream = resource.getInputStream(); // Do something with the input stream }