Java资源作为文件

Java资源作为文件,java,resources,classloader,Java,Resources,Classloader,Java中有没有一种方法可以在通过类加载器从jar检索到的资源上构造一个文件实例 我的应用程序使用jar(默认)或运行时指定的文件系统目录(用户输入)中的一些文件。我正在寻找一种一致的方法 a) 将这些文件作为流加载 b) 分别列出用户定义目录或jar目录中的文件 编辑:显然,理想的方法是完全远离java.io.File。有没有办法从类路径加载目录并列出其内容(其中包含的文件/实体)?尝试以下方法: ClassLoader.getResourceAsStream ("some/pkg/resou

Java中有没有一种方法可以在通过类加载器从jar检索到的资源上构造一个文件实例

我的应用程序使用jar(默认)或运行时指定的文件系统目录(用户输入)中的一些文件。我正在寻找一种一致的方法
a) 将这些文件作为流加载
b) 分别列出用户定义目录或jar目录中的文件

编辑:显然,理想的方法是完全远离java.io.File。有没有办法从类路径加载目录并列出其内容(其中包含的文件/实体)?

尝试以下方法:

ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
还有更多可用的方法,例如,请参见此处:
ClassLoader.getResourceAsStream
Class.getResourceAsStream
无疑是加载资源数据的方法。但是,我不相信有任何方法可以“列出”类路径元素的内容

在某些情况下,这可能根本不可能——例如,
ClassLoader
可以根据请求的资源名称动态生成数据。如果您查看
ClassLoader
API(这基本上就是类路径机制的工作原理),您会发现没有什么可以做的

如果您知道您实际上有一个jar文件,您可以使用
ZipInputStream
加载该文件,以了解可用的内容。这意味着您将有不同的目录和jar文件代码


如果先单独创建这些文件,另一种方法是包含一种清单文件,其中包含可用资源的列表。将其捆绑到jar文件中,或将其作为文件包含在文件系统中,并在为用户提供资源选择之前加载它。

我遇到了同样的问题,并且能够使用以下内容:

// 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()

这是一个选项:

这里是我的一个应用程序中的一些代码。。。 让我知道它是否适合你的需要。 如果您知道要使用的文件,可以使用此选项

URL defaultImage = ClassA.class.getResource("/packageA/subPackage/image-name.png");
File imageFile = new File(defaultImage.toURI());

希望有帮助。

在从jar检索到的资源上构造文件实例的可靠方法是将资源作为流复制到临时文件中(JVM退出时临时文件将被删除):


谢谢你的回复。我知道getResourceAsStream,但我认为我无法通过它从类路径加载目录。在Java中,目录是一个文件(我想是UNIX根目录),所以您至少应该尝试一下。我认为要在目录中列出文件,您需要使用Java.io.file。您可以使用ClassLoader.findResource查找文件,它返回可以传递到文件的URL。我同意这很烦人,但它使ClassLoader在其他方面更广泛地适用。例如,编写“web类加载器”很容易,因为web非常适合获取文件,但它通常不列出文件。如果您试图加载的资源比1MiB大得多,则从
getResourceAsStream
获取的
InputStream
会停止检索该大小后的资源字节,如果它包含在压缩文件系统(如jar)中,则返回0。在这种情况下,您似乎被迫使用
getResource
并独立加载文件。@mgttlinger:我觉得这不太可能。。。如果可以的话,可能值得发布一个带有repo的新问题。这个问题是由于
read
方法决定了要读取多少数据(我不知道)。如果要读取的文件位于常规文件夹中,则整个文件似乎都被读取。如果该文件由于已打包而位于jar中,它将只读取其中的一部分。@mgttlinger:不,它不会只读取其中的一部分,但它可能不会填充每次读取调用时提供的整个缓冲区。与
InputStream
一样,如果要读取整个资源,应该循环直到
read
返回-1。这种方法不适用于类路径中的JAR,只适用于文件和directories@yegor256如果您的文件位于jar中,您可以创建一个
文件系统
对象,并从中获取
路径
。然后你就可以像平常一样读了。(请参阅)虽然此链接可以回答问题,但在此处包含答案的基本部分,并提供链接供参考,因为链接可能会更改或删除链接页面,从而使答案无效。是的,但
toURI()
将失败。
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;
    }
}