如何从.jar加载文件夹?

好。 所以我有一个非常简单的问题:我希望能够从正在运行的.jar文件中加载资源(整个文件夹),但我无法让它工作。 这是我尝试过的(如果类名是“myClass”,文件夹名为“myFolder”),但它总是抛出NullPointerException:

URL folderURL = myClass.class.getClassLoader().getResource("myFolder/"); String folderPath = folderURL.getPath(); File myFolder = new File(folderPath); 

在创建“myFolder”之前,总是抛出NullPointerException。

更多信息:我必须从静态上下文访问该文件夹。 正在访问该文件夹的类与文件夹本身所在的目录不在同一目录中。(该文件夹位于jar内的根目录中,该类是几个子包。)

有没有人能解决我的问题? 对不起,如果我使用了错误的术语:P,但您可以做任何事情来帮助我们。

这是行不通的。 您正在尝试从JAR内的资源创建File对象。 这不会发生。 加载资源的最佳方法是将一个包文件夹作为资源文件夹,然后在其中创建一个Resources.jar,将资源转储到同一目录中,然后在其他目录中使用Resources.class.getResourceAsStream(resFileName) Java类文件。

如果你需要“暴力破解”由getResource(..)给出的URL指向的JAR目录中的子文件,请使用以下内容(尽管这有点像黑客!)。 它也适用于普通的文件系统:

  /** * List directory contents for a resource folder. Not recursive. * This is basically a brute-force implementation. * Works for regular files and also JARs. * * @author Greg Briggs * @param clazz Any java class that lives in the same place as the resources you want. * @param path Should end with "/", but not start with one. * @return Just the name of each member item, not the full paths. * @throws URISyntaxException * @throws IOException */ String[] getResourceListing(Class clazz, String path) throws URISyntaxException, IOException { URL dirURL = clazz.getClassLoader().getResource(path); if (dirURL != null && dirURL.getProtocol().equals("file")) { /* A file path: easy enough */ return new File(dirURL.toURI()).list(); } if (dirURL == null) { /* * In case of a jar file, we can't actually find a directory. * Have to assume the same jar as clazz. */ String me = clazz.getName().replace(".", "/")+".class"; dirURL = clazz.getClassLoader().getResource(me); } if (dirURL.getProtocol().equals("jar")) { /* A JAR path */ String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); Enumeration entries = jar.entries(); //gives ALL entries in jar Set result = new HashSet(); //avoid duplicates in case it is a subdirectory while(entries.hasMoreElements()) { String name = entries.nextElement().getName(); if (name.startsWith(path)) { //filter according to the path String entry = name.substring(path.length()); int checkSubdir = entry.indexOf("/"); if (checkSubdir >= 0) { // if it is a subdirectory, we just return the directory name entry = entry.substring(0, checkSubdir); } result.add(entry); } } return result.toArray(new String[result.size()]); } throw new UnsupportedOperationException("Cannot list files for URL "+dirURL); } 

然后,您可以修改getResource(..)给出的URL并将文件附加到末尾,并将这些URL传递给getResourceAsStream(..) ,以备加载。 如果你不明白这一点,你需要阅读类加载。

这很简单:

 getClass().getResourceAsStream("/resources/images/myImage.png") 

将返回一个可以像这样使用的输入流:

 Image myImage = ImageIO.read(getClass().getResourceAsStream("/resources/images/myImage.png")); 

从那里,按照你喜欢的方式使用你的Image。 如果您使用输入流来读取文本文件,或者几乎无论您正在做什么,这也可以正常工作。

编辑:上面的路径是相对于.jar的根。

我想我正在做点什么。 在Eclipse中,创建一个名为“resources”的新源文件夹,并在该文件夹中创建一个名为“myFolder”的包。 要拥有“myFolder”的路径,您只需说:

 Path path = Paths.get(Main.class.getResource("/myFolder").toURI()); // or the class name instead of Main 

到目前为止(2017年12月),这是我发现的唯一可在IDE内部和外部工作的解决方案(使用PathMatchingResourcePatternResolver ): https : //stackoverflow.com/a/47904173/6792588