如何从 .jar 加载文件夹? [英] How to load a folder from a .jar?

查看:35
本文介绍了如何从 .jar 加载文件夹?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

OK. So I have a pretty simple question: I want to be able to load a resource (a whole folder) from inside a running .jar file, but I have not been able to get it to work. This is what I have tried (if the class name were "myClass" and the folder being called "myFolder"), but it always throws a NullPointerException:

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

在我创建myFolder"之前总是抛出 NullPointerException.

The NullPointerException is always thrown before I create "myFolder".

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

Some more info: I have to access the folder from static context. The class that is accessing the folder is NOT in the same directory as the folder itself is in. (The folder is in the root directory inside the jar, the class is a couple subpackages down.)

有人能解决我的问题吗?抱歉,如果我使用了错误的术语:P,但您可以提供任何帮助,我们将不胜感激.

Does anyone have a solution to my problem? Sorry if I used wrong terminology :P, but anything you can do to help is appreciated.

推荐答案

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

There's no way this will work. You're trying to create a File object from a resource inside a JAR. That isn't going to happen. The best method to load resources is to make one your package folders a resource folder, then make a Resources.jar in it or something, dump your resources in the same dir, and then use Resources.class.getResourceAsStream(resFileName) in your other Java class files.

如果您需要对 getResource(..) 给出的 URL 指向的 JAR 目录中的子文件进行暴力破解",请使用以下命令(尽管这有点小技巧!).它也适用于普通文件系统:

If you need to 'brute force' the subfiles in the JAR directory pointed to by the URL given by getResource(..), use the following (although it's a bit of a hack!). It will work for a normal filesystem too:

  /**
   * 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<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        Set<String> result = new HashSet<String>(); //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(..),准备好用于加载.如果你不明白这一点,你需要阅读类加载.

You can then modify the URL given by getResource(..) and append the file on the end, and pass these URLs into getResourceAsStream(..), ready for loading. If you didn't understand this, you need to read up on classloading.

这篇关于如何从 .jar 加载文件夹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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