Java如何在jar环境而不是IDE中读取文件夹并列出该文件夹中的文件

标签 java jar iostream

我的问题是我在 src 下创建了一个文件夹(名称是 IconResources),在 IconResources 中有很多图片。目录是这样的:

  • 项目名称
    • 来源
      • 套餐1
      • 套餐2
      • IconResources(这是目标文件夹)

我想列出所有图片文件名并对这些图片做一些处理。而且我发现 File.list() 只能在 IDE 中工作,如果我将项目导出到 jar 以独立运行,它就无法工作。于是搜索了一下,发现应该使用inputstream和outputstream。现在我发现 i/o 流可以很好地处理单个文件。但我想使用输入流和输出流来读取文件夹(IconResource),然后列出该文件夹中的文件。

所以我的问题是如何使用 i/o put 流加载文件夹并迭代文件夹以列出该文件夹中的文件名。这些东西不仅应该在 IDE 下工作,而且应该在导出的 jar 下工作。 我的代码如下:

private void initalizeIconFiles(File projectDirectory){

    URL a = editor.getClass().getResource("/IconResources/");// Get Folder URL
    List<String> iconFileNames=new ArrayList<String>();//Create a list to store file names from IconResource Folder
    File iconFolder = new File(a.getFile());
    Path path=Paths.get(iconFolder.getPath());
    DirectoryStream<Path> stream = Files.newDirectoryStream(path) ;
    for (Path entry : stream) {
        if (!Files.isDirectory(entry)) {
            System.out.println(entry.getFileName().toString());
            iconFileNames.add(entry.getFileName().toString());// add file name in to name list
        }
    }
}

以上代码只能在IDE下运行,但在导出的jar中会崩溃。

最佳答案

这实际上是一个非常困难的问题,因为 ClassLoader必须考虑到您可能有一个名为 IconResources另一个 文件夹在运行时的类路径上。

因此,没有“官方”方法可以从类路径中列出整个文件夹。我在下面给出的解决方案是一个 hack,目前适用于 URLClassLoader 的实现。 .这可能会发生变化。

如果你想要稳健的方法,你将需要使用类路径扫描器。有很多图书馆形式的,我个人最喜欢的是Reflections ,但 Spring 内置了一个,还有许多其他选项。

进入黑客。

一般来说,如果你 getResourceAsStream URLClassLoader 上然后它将返回该文件夹中的资源流,每行一个。 URLClassLoader是 JRE 使用的默认设置,因此如果您不更改该行为,这种方法应该开箱即用。

假设我有一个具有以下类路径结构的项目:

/
    text/
        one.txt
        two.txt

然后运行以下代码:

final ClassLoader loader = Thread.currentThread().getContextClassLoader();
try(
        final InputStream is = loader.getResourceAsStream("text");
        final InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
        final BufferedReader br = new BufferedReader(isr)) {
    br.lines().forEach(System.out::println);
}

将打印:

one.txt
two.txt

所以,为了得到一个List<URL>该位置的资源的一部分,您可以使用以下方法:

public static List<URL> getResources(final String path) throws IOException {
    final ClassLoader loader = Thread.currentThread().getContextClassLoader();
    try (
            final InputStream is = loader.getResourceAsStream(path);
            final InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
            final BufferedReader br = new BufferedReader(isr)) {
        return br.lines()
                .map(l -> path + "/" + l)
                .map(r -> loader.getResource(r))
                .collect(toList());
    }
}

现在记住,这些URL位置不透明。它们不能被视为文件,因为它们可能位于 .jar 中。或者他们甚至可能在互联网上。因此,为了读取资源的内容,请在 URL 上使用适当的方法。 :

final URL resource = ...
try(final InputStream is = resource.openStream()) {
    //do stuff
}

关于Java如何在jar环境而不是IDE中读取文件夹并列出该文件夹中的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28985379/

相关文章:

java - 如何设置两个垂直分割 Pane ,以便拖动每个 Pane 不会影响另一个 Pane ?

从远程服务器下载文件到Android手机时出现java.io.eofException

java - 托管 Jar 文件

c# - 是否可以在 Stream 参数中限制/要求某些功能?

c++ - 重载的 std::ostream operator<< 未调用,流获取变量地址而不是对象

Java:如何在运行时获取泛型类型?

java - 如何组合图像以用作 SWT 光标

Java 在 Lucene 中为 contrib 包创建 JAR 文件

java - 为什么 jar 忽略我的 list ?

c++ - 无符号变量的默认值是多少?