0

我有一个用例,我需要将这段特定的代码导出为 java 库(最终将是一个 JAR),但问题是它需要使用存储在文件系统上的物理文件中的一些信息。

我在这里有两个问题:

1)我应该将这些文件放在文件系统的哪里(我能想到的一个选项是在包含库的 Java 模块的资源目录中:尽管资源目录也被编译到 jar 中,但有疑问吗?)

2) 当我从外部 Java 应用程序使用这个库时,该库如何能够找到这些文件?他们还会在类路径中吗?

4

5 回答 5

1

您有两个选择,第一个是将文件放在包结构中,以便将它们打包在 jar 中。你会从这样的代码中得到它们:

getClass().getResourceAsStream("/path/to/your/resource/resource.ext");

如果您要从名为 A 的类的静态方法中调用它,那么您应该这样编写:

A.class.getResourceAsStream("/path/to/your/resource/resource.ext");

路径的“/path”部分是最顶层的包,resource.ext 是你的文件名。

另一种选择是将它们放在 jar 包之外,但是 jar 需要知道它们的位置:

  • 将其作为参数提供给程序(java -jar program.jar system/path/to/file)
  • 硬编码您将使用路径读取文件的位置

我解开你的问题并回答它的方式,它与classpath无关:

CLASSPATH 变量是告诉应用程序(包括 JDK 工具)在哪里查找用户类的一种方式。(属于 JRE、JDK 平台和扩展的类应通过其他方式定义,例如引导类路径或扩展目录。)

编辑:但是您仍然可以将其放在那里并从如下代码中获取:

System.getProperty("java.class.path");

然而,它需要一些逻辑来解析它。

于 2012-10-09T10:37:59.520 回答
0

您可以在属性文件或类似的技术中传递文件的位置。

于 2012-10-09T10:28:48.150 回答
0

我应该把这些文件放在文件系统的什么地方

这由您来决定,尽管将其设置为可配置是一个好主意。尝试适应主机操作系统/发行版的约定也是一个好主意,尽管这些会有所不同……并且取决于您的应用程序的性质。

当我从外部 Java 应用程序使用这个库时,该库如何能够找到这些文件?

您通常会使用配置属性或初始化参数来保存/传递位置。如果您正在编写应用程序而不是库,则可以使用Java Preferences API,尽管这对于库来说可能是一个糟糕的选择。

他们还会在类路径中吗?

仅当您将位置放在类路径上时……这将使配置更加棘手。鉴于这些文件需要存储在文件系统中,我建议使用FileInputStream或类似的。

于 2012-10-09T10:35:32.927 回答
0

使用 Eclipse,我总是创建一个包“资源”,在其中放置 jar 需要的文件。我通过以下方式访问文件(几乎可以从任何地方)

this.getClass().getClassLoader().getResources("/resources/file.ext");

使用export->runnable jar,所有这些文件都包含在 .jar 中。我不确定这是不是正确的做法。另外,我不是 100% 确定资源前的“/”,也许应该省略它。

于 2012-10-09T10:36:36.793 回答
0

作为另一个问题的一部分,我找到了一个相关答案:如何从 .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<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);
  }
于 2012-10-15T09:54:26.860 回答