如何从我的jar文件中获取资源"文件夹"?

Mos*_*ali 123 java directory resources list

我在项目的根目录中有一个资源文件夹/包,我"不"想要加载某个文件.如果我想加载某个文件,我会使用class.getResourceAsStream,我会没事的!我真正想要做的是在资源文件夹中加载一个"文件夹",循环该文件夹内的文件并获取每个文件的流并读入内容...假设在运行时之前未确定文件名... 我该怎么办?有没有办法在jar文件中获取文件夹中的文件列表?请注意,带有资源的Jar文件与运行代码的jar文件相同...

提前致谢...

use*_*877 107

最后,我找到了解决方案:

final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());

if(jarFile.isFile()) {  // Run with JAR file
    final JarFile jar = new JarFile(jarFile);
    final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
    while(entries.hasMoreElements()) {
        final String name = entries.nextElement().getName();
        if (name.startsWith(path + "/")) { //filter according to the path
            System.out.println(name);
        }
    }
    jar.close();
} else { // Run with IDE
    final URL url = Launcher.class.getResource("/" + path);
    if (url != null) {
        try {
            final File apps = new File(url.toURI());
            for (File app : apps.listFiles()) {
                System.out.println(app);
            }
        } catch (URISyntaxException ex) {
            // never happens
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个块只在IDE上运行应用程序时工作(不是使用jar文件),如果不喜欢,可以删除它.

  • 仅供参考,如果从webstart启动,这不起作用,因为getPath返回相对于服务器域的内容. (4认同)
  • 如果路径位于 jar 中,则不要认为它会起作用,在 toURI 转换时会出现此错误:java.lang.IllegalArgumentException:URI 不是分层的 (2认同)
  • 仅适用于单个jar文件,不适用于从另一个jar中的依赖项提取资源 (2认同)
  • 这不是一个安全的解决方案,因为: 1. 它假设 .jar 文件是同一系统上的本地文件;2. URL.getPath() 不返回有效的文件名,它只返回 URL 的路径部分,所有百分比转义都完好无损;3. [ProtectionDomain.getCodeSource() 可以返回null](https://docs.oracle.com/javase/9​​/docs/api/java/security/ProtectionDomain.html#getCodeSource--)。 (2认同)

Gle*_*est 15

请尝试以下方法. 如果您的类路径是com.abc.package.MyClass并且您
的资源"<PathRelativeToThisClassFile>/<ResourceDirectory>"文件位于src/com/abc/package/resources /中,请创建资源路径Eg:

URL url = MyClass.class.getResource("resources/");
if (url == null) {
     // error - missing folder
} else {
    File dir = new File(url.toURI());
    for (File nextFile : dir.listFiles()) {
        // Do something with nextFile
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以使用

URL url = MyClass.class.getResource("/com/abc/package/resources/");
Run Code Online (Sandbox Code Playgroud)

  • 感谢您花费时间和精力,但是当您的代码基于.jar文件并且您的资源也位于.jar文件中时,这不起作用.当你在.jar文件中时,你不能创建一个文件(),你也无法获得该文件夹的URL ...我亲自与它和平,并在XML中列出每个文件......我不知道t认为你可以为jar文件中的文件夹做到这一点...... (23认同)
  • OP不使用文件和目录.他正在使用JAR文件中的资源.JAR文件中的资源不是文件或目录,不能与`File`类一起列出.此代码不适用于JAR文件中的资源.期. (4认同)
  • 从javadoc来看,显然该方法并不总是保证在所有情况下都返回一个文件.但是,如果您确实阅读了Q,那么OP将100%保证通过构造处理文件和文件夹.Q要求访问目录和文件 - 这更具体是API的通用抽象.转换为文件是恰当和正确的,以满足需要.在发布此类强烈反对意见之前,请正确阅读问卷.干杯. (3认同)
  • 对不起,你有问题.但是,当您的代码库位于jar文件中并且您的资源也在该jar文件中时,它确实有效.您没有在磁盘上创建File() - 您正在将jar文件中的File读入java内存.请注意,ClassLoader非常乐意将jar文件视为等同于磁盘上的目录.以下是来源的详细信息: (2认同)

hum*_*ngV 13

以下代码将所需的“文件夹”作为路径返回,无论它是否位于 jar 内。

  private Path getFolderPath() throws URISyntaxException, IOException {
    URI uri = getClass().getClassLoader().getResource("folder").toURI();
    if ("jar".equals(uri.getScheme())) {
      FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
      return fileSystem.getPath("path/to/folder/inside/jar");
    } else {
      return Paths.get(uri);
    }
  }
Run Code Online (Sandbox Code Playgroud)

需要 java 7+。


小智 7

我知道这是多年前的事了.但只是为了其他人遇到这个话题.你可以做的是使用getResourceAsStream()带有目录路径的方法,输入Stream将拥有该目录中的所有文件名.之后,您可以使用每个文件名连接dir路径,并为循环中的每个文件调用getResourceAsStream.

  • 事实证明,除非你计划将事情搞砸,否则这种方法很有效. (7认同)

SQL*_*ion 5

当我试图从jar中包装的资源加载一些hadoop配置时,我在IDE和jar(发布版本)上遇到了同样的问题.

我发现java.nio.file.DirectoryStream最好在本地文件系统和jar上迭代目录内容.

String fooFolder = "/foo/folder";
....

ClassLoader classLoader = foofClass.class.getClassLoader();
try {
    uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
    throw new FooException(e.getMessage());
} catch (NullPointerException e){
    throw new FooException(e.getMessage());
}

if(uri == null){
    throw new FooException("something is wrong directory or files missing");
}

/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
    /** jar case */
    try{
        URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
        //jar.toString() begins with file:
        //i want to trim it out...
        Path jarFile = Paths.get(jar.toString().substring("file:".length()));
        FileSystem fs = FileSystems.newFileSystem(jarFile, null);
        DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
        for(Path p: directoryStream){
            InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
        performFooOverInputStream(is);
        /** your logic here **/
            }
    }catch(IOException e) {
        throw new FooException(e.getMessage());     
    }
}
else{
    /** IDE case */
    Path path = Paths.get(uri);
    try {
        DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
        for(Path p : directoryStream){
            InputStream is = new FileInputStream(p.toFile());
            performFooOverInputStream(is);
        }
    } catch (IOException _e) {
        throw new FooException(_e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)