在Java中,是否有一种方法可以通过类加载器从jar中检索到资源并构建一个File
实例?
我的应用程序使用来自jar(默认)或在运行时指定的文件系统目录中的某些文件(用户输入)。我正在寻找一种一致的方法
a)将这些文件作为流加载
b)分别列出用户定义的目录或jar中的目录中的文件
编辑:显然,理想方法是完全避开java.io.File
。是否有一种方法可以从类路径加载目录并列出其内容(其中包含的文件/实体)?
在Java中,是否有一种方法可以通过类加载器从jar中检索到资源并构建一个File
实例?
我的应用程序使用来自jar(默认)或在运行时指定的文件系统目录中的某些文件(用户输入)。我正在寻找一种一致的方法
a)将这些文件作为流加载
b)分别列出用户定义的目录或jar中的目录中的文件
编辑:显然,理想方法是完全避开java.io.File
。是否有一种方法可以从类路径加载目录并列出其内容(其中包含的文件/实体)?
我遇到了同样的问题,并且成功地使用了以下方法:
// Load the directory as a resource
URL dir_url = ClassLoader.getSystemResource(dir_path);
// Turn the resource into a File object
File dir = new File(dir_url.toURI());
// List the directory
String files = dir.list()
ClassLoader.getResourceAsStream
和Class.getResourceAsStream
是从资源中加载数据的方法,但是我认为没有任何方式可以"列出"类路径元素的内容。
在某些情况下这可能是不可能的。例如,一个ClassLoader
可以根据所请求的资源名称实时生成数据。如果你查看ClassLoader
API(它基本上是类路径机制工作的原理),你会发现没有任何东西能够做到你想要的。
如果你知道你实际上有一个jar文件,那么你可以使用ZipInputStream
来查找可用的内容。这意味着你需要为目录和jar文件编写不同的代码。
另一种选择是,如果文件是先单独创建的,可以包含一种包含可用资源列表的清单文件。把它打包到jar文件中或将其作为一个文件包含在文件系统中,在向用户提供可选资源之前先加载它。
getResourceAsStream
获取的InputStream
在该大小后停止检索资源的字节,并且如果它包含在压缩文件系统(如jar)中,则返回0。在这种情况下,您似乎被迫使用getResource
并独立加载文件。 - mgttlingerread
方法决定读取多少数据(我不知道这一点)导致的。如果被读取的文件位于常规文件夹中,则似乎会读取整个文件。如果文件在jar包中,因为已经打包,它只会读取部分内容。 - mgttlingerInputStream
一样,如果您想读取整个资源,应该循环直到read
返回-1。 - Jon Skeet这是我一个应用程序中的一部分代码... 如果符合您的需求,请告诉我。 如果您知道要使用的文件,可以使用此代码。
URL defaultImage = ClassA.class.getResource("/packageA/subPackage/image-name.png");
File imageFile = new File(defaultImage.toURI());
toURI()
会失败。 - Olivier Faucheux构建从JAR中检索的资源的文件实例的可靠方法是将该资源作为流复制到临时文件中(当JVM退出时,临时文件将被删除):
一个可靠的方法是将JAR中检索的资源作为流复制到临时文件中,以此来构建File实例(在JVM退出时会删除临时文件):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
试试这个:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
还有其他可用的方法,例如在这里查看: http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
FileSystem
对象并从中获取Path
。然后你可以像平常一样读取它。(参见https://dev59.com/SGEh5IYBdhLWcg3wRRqh#22605905) - mgttlinger