我有一个用例,我需要将这段特定的代码导出为java库(最终将是一个JAR),但问题是它需要使用存储在文件上的物理文件中的一些信息系统
我在这里有两个问题:
1)我应该把这些文件放在文件系统上(我能想到的一个选项是在包含库的Java模块的resources目录中:虽然资源目录也被编译到jar中但有疑问? )
2)当我从外部Java应用程序使用此库时,库如何能够找到文件?他们还会在课堂上吗?
答案 0 :(得分: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需要知道它们的位置:
我不知道你的问题并回答它的方式,它与classpath无关:
CLASSPATH变量是告诉应用程序(包括JDK工具)查找用户类的一种方法。 (属于JRE,JDK平台和扩展的类应该通过其他方式定义,例如引导类路径或扩展目录。)
编辑: 但你可以把它放在那里,从这样的代码中得到它:
System.getProperty("java.class.path");
然而,需要一些逻辑来解析它。
答案 1 :(得分:0)
您可以在属性文件或类似的技术中传递文件的位置。
答案 2 :(得分:0)
我应该把这些文件放在文件系统上
由您来决定,尽管让这个可配置是个好主意。尝试适应主机操作系统/发行版的约定也是一个好主意,尽管这些约会有所不同......并且取决于应用程序的性质。
当我从外部Java应用程序使用此库时,库如何能够找到文件?
通常使用配置属性或初始化参数来保存/传递位置。如果您正在编写应用程序而不是库,则可以使用Java Preferences APIs,尽管这可能是库的不良选择。
他们还会在课堂上吗?
仅当您将位置放在类路径上时......这将使配置更加棘手。鉴于这些文件需要存储在文件系统中,我建议使用FileInputStream
或类似文件。
答案 3 :(得分:0)
使用Eclipse,我总是创建一个包'resources'来放置jar所需的文件。我通过
访问文件(几乎从任何地方)this.getClass().getClassLoader().getResources("/resources/file.ext");
使用 export-> runnable jar ,所有这些文件都包含在.jar中。我不确定这是否是正确的做法。另外,我对资源之前的“/”并不是100%肯定,也许应该省略。
答案 4 :(得分:0)
我在另一个问题中找到了相关的答案:How to load a folder from a .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);
}