Java如何在jar环境中而不是IDE中读取该文件夹中的文件夹和列表文件 [英] Java how to read folder and list files in that folder in jar environment instead of IDE

查看:171
本文介绍了Java如何在jar环境中而不是IDE中读取该文件夹中的文件夹和列表文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

my problem is that I create a folder(name is IconResources) under src , in IconResources there are many pictures. Directory is like this:


  • ProjectName


    • src


      • package 1

      • package 2

      • IconResources(这是目标文件夹)

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

      I want to list all picture files name and do something with those pictures. And I found that File.list() only works in IDE, if I export project to a jar to make a standalone, it cannot work. So I searched and found that I should use inputstream and outputstream. Now I find i/o stream can works well for single file. But I want to use inputstream and outputstream to read folder(IconResource), then list the files in that folder.

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

      So my question is how to use i/o put stream to load a folder and iterate the folder to list file names in that folder. These things should work under not only IDE but also exported jar. My code are follows:

      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中分解。

      above code only can run under IDE but break down in exported jar.

      推荐答案

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

      This is actually a very difficult question, as the ClassLoader has to take account of the fact that you might have another folder called IconResources on the classpath at runtime.

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

      As such, there is no "official" way to list an entire folder from the classpath. The solution I give below is a hack and currently works with the implementation of URLClassLoader. This is subject to change.

      如果你想要强大的方法,你需要使用类路径扫描程序。其中有很多是图书馆形式,我个人最喜欢的是反思,但Spring有一个内置in和还有很多其他选择。

      If you want to robust approach, you will need to use a classpath scanner. There are many of these in library form, my personal favourite is Reflections, but Spring has one built in and there are many other options.

      在黑客攻击中。

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

      Generally, if you getResourceAsStream on a URLClassLoader then it will return a stream of the resources in that folder, one on each line. The URLClassLoader is the default used by the JRE so this approach should work out of the box, if you're not changing that behaviour.

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

      Assume I have a project with the following classpath structure:

      /
          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

      one.txt
      two.txt

      所以,为了获取列表< URL> 该位置的资源,您可以使用以下方法:

      So, in order to get a List<URL> of the resources in that location you could use a method such as:

      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());
          }
      }
      

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

      Now remember, these URL locations are opaque. They cannot be treated as files, as they might be inside a .jar or they might even be at an internet location. So in order to read the contents of the resource, use the appropriate methods on URL:

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

      这篇关于Java如何在jar环境中而不是IDE中读取该文件夹中的文件夹和列表文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆