ClassLoader.getResourceAsStream是如何工作的? [英] How does ClassLoader.getResourceAsStream work?

查看:19
本文介绍了ClassLoader.getResourceAsStream是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用Maven创建了一个JAR文件。当我打开这个罐子时,我可以找到以下内容:

my.jar
|_text1.txt
|_folder
|_ ... some other stuff

当我在Eclipse中运行此代码片段时,";ext1.txt";的内容以及输出的文件夹内容中的所有文件名

String tmp = IOUtils.toString(App.class.getClassLoader().getResourceAsStream("text1.txt"), StandardCharsets.UTF_8);
System.err.println(tmp);
            
tmp = IOUtils.toString(App.class.getClassLoader().getResourceAsStream("folder"), StandardCharsets.UTF_8);
System.err.println(tmp);

当我将此代码作为独立程序运行时,也将打印来自";ext1.txt";的内容,但文件夹的第二部分返回空。

我做错了什么?

推荐答案

App.class.getClassLoader().getResourceAsStream

不要这样做。正确的方式是App.class.getResourceAsStream。有些时候getCLassLoader()返回NULL;在这种情况下,您的策略失败了,上面的方法可以很好地工作。此外,您的方式是更多的调用和更多的代码,而不会获得任何好处。

IOUtils.toString(App.class.getClassLoader().getResourceAsStream("folder")

您无法获取"文件夹"。你觉得这会有什么用呢?设计到资源加载器系统中的抽象(这就是您在这里使用的)不允许您以任何方式获取文件夹,也不允许您列出文件夹的内容。(您可能正在寻找SPI:服务提供商接口)。

IOUtils

您不需要这个;java.nio.file.Files是内置的,并且同样有一个toString方法。它甚至默认为UTF-8,因此您不必指定它。

App.class.getResourceAsStream("text1.txt")

这将在与App.class完全相同的位置查找t1.txt。甚至是相同的包装结构。如果您想从App.class所在位置的"根"开始(因此,通常是-classpath上的内容),请在前面加一个斜杠:例如,请求"/text1.txt"

假设您的ext1.txt位于根目录中,而不是com/foo/pkg/MyApp.class旁边的com/foo/pkg中,则需要指定"/text1.txt"才能找到它。

如果您不确定此内容的位置,请输出此调用的结果:

App.class.getResource("App.class");

这会打印一个URL,您的眼球将能够从它看到它的位置。

和打印出的文件夹内容中的所有文件名

那很好。这不起作用--eclipse在运行时为您提供了这是一种怪异,但规范基本上没有对此进行抽象。ClassLoader实现可以做他们想做的任何事情(这是一个可插拔的系统),它们需要实现的唯一方法是"在这个位置找到资源"。如果您请求一个‘文件夹’,则没有义务返回文件名字符串,而且大多数类加载器(包括读取JAR文件的类加载器)根本不需要这样做。

解决方案是SPI:在编译时创建一个列出路径或类名的文件,然后在运行时使用资源系统加载该文件,然后加载其中列出的每个类/每个资源。作为编译的一部分,注释处理器可以自动生成此文件的过程,从而使整个测试过程无缝进行。在Web上搜索SPI Java以了解更多信息。

这篇关于ClassLoader.getResourceAsStream是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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