Aza*_*Aza 163 java file-io resources
我正在我的Java项目的已编译JAR中的包中加载一个文本文件.相关目录结构如下:
/src/initialization/Lifepaths.txt
Run Code Online (Sandbox Code Playgroud)
用于加载文件的代码是:
public class Lifepaths {
public static void execute() {
System.out.println(Lifepaths.class.getClass().
getResourceAsStream("/initialization/Lifepaths.txt"));
}
private Lifepaths() {}
//This is temporary; will eventually be called from outside
public static void main(String[] args) {execute();}
}
Run Code Online (Sandbox Code Playgroud)
null无论我使用什么,打印输出都会打印出来.我不确定为什么以上都行不通,所以我也尝试过:
"/src/initialization/Lifepaths.txt""initialization/Lifepaths.txt""Lifepaths.txt"这些都不奏效.我 读 了许多 问题至今的话题,但他们都不是有帮助的-通常情况下,他们只是说来加载使用根路径,这我已经在做的文件.那,或者只是从当前目录加载文件(只是加载filename),我也尝试过.该文件正在具有适当名称的适当位置编译到JAR中.
我该如何解决这个问题?
hoa*_*oaz 145
Lifepaths.class.getClass().getResourceAsStream(...) 使用系统类加载器加载资源,它显然失败,因为它没有看到你的JAR
Lifepaths.class.getResourceAsStream(...) 使用加载Lifepaths类的相同类加载器加载资源,它应该可以访问JAR中的资源
Puc*_*uce 55
规则如下:
并尝试:
Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")
Run Code Online (Sandbox Code Playgroud)
代替
Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")
Run Code Online (Sandbox Code Playgroud)
(不确定它是否有所作为,但前者将使用正确的ClassLoader/JAR,而我不确定后者)
gre*_*dha 44
因此,有几种方法可以从jar获取资源,每种方法的语法略有不同,其中路径需要以不同方式指定.
我所看到的最好的解释是来自JavaWorld的这篇文章.我将在这里总结,但如果你想了解更多,你应该查看这篇文章.
方法
1)ClassLoader.getResourceAsStream().
格式:"/" - 分隔名称; 没有前导"/"(所有名称都是绝对的).
例: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2) Class.getResourceAsStream()
格式:"/" - 分隔名称; 前导"/"表示绝对名称; 所有其他名称都相对于类的包
例: this.getClass().getResourceAsStream("/some/pkg/resource.properties");
Pau*_*ith 14
不要使用绝对路径,使它们相对于项目中的"resources"目录.快速而脏的代码,显示目录"resources"中MyTest.txt的内容.
@Test
public void testDefaultResource() {
// can we see default resources
BufferedInputStream result = (BufferedInputStream)
Config.class.getClassLoader().getResourceAsStream("MyTest.txt");
byte [] b = new byte[256];
int val = 0;
String txt = null;
do {
try {
val = result.read(b);
if (val > 0) {
txt += new String(b, 0, val);
}
} catch (IOException e) {
e.printStackTrace();
}
} while (val > -1);
System.out.println(txt);
}
Run Code Online (Sandbox Code Playgroud)
您可能想尝试这个来获取流,即首先获取URL,然后将其作为流打开.
URL url = getClass().getResource("/initialization/Lifepaths.txt");
InputStream strm = url.openStream();
Run Code Online (Sandbox Code Playgroud)
我曾经有一个类似的问题:从jar读取txt文件失败但读取图像有效
我发现自己遇到了类似的问题。由于我使用的是 maven,因此我需要更新我的 pom.xml 以包含如下内容:
...
</dependencies>
<build>
<resources>
<resource>
<directory>/src/main/resources</directory>
</resource>
<resource>
<directory>../src/main/resources</directory>
</resource>
</resources>
<pluginManagement>
...
Run Code Online (Sandbox Code Playgroud)
请注意其中的资源标签以指定该文件夹的位置。如果您有嵌套项目(就像我一样),那么您可能希望从其他区域获取资源,而不仅仅是在您正在使用的模块中。如果您使用类似的配置数据,这有助于减少在每个 repo 中保留相同的文件
您正在使用的ClassLoader似乎存在问题.使用contextClassLoader加载类.这与它是否采用静态/非静态方法无关
Thread.currentThread().getContextClassLoader().getResourceAsStream......
默认的 JVM 类加载器将首先使用父类加载器加载资源:
。
Lifepaths.class.getClass()的类加载器是bootstrap classloader,因此getResourceAsStream将仅搜索 $JAVA_HOME ,无论用户提供什么classpath。显然,Lifepaths.txt 不存在。
Lifepaths.class的类加载器是system classpath classloader,因此getResourceAsStream将搜索用户定义的classpath并且 Lifepaths.txt 就在那里。
使用 时,将添加不以“/”java.lang.Class#getResourceAsStream(String name)开头的名称作为前缀。为了避免这种情况使用。package namejava.lang.ClassLoader#getResourceAsStream
例如:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String resourceName = "Lifepaths.txt";
InputStream resourceStream = loader.getResourceAsStream(resourceName);
Run Code Online (Sandbox Code Playgroud)
大致说来:
getClass().getResource("/") ~= Thread.currentThread().getContextClassLoader().getResource(".")
假设您的项目结构如下所示:
??? src
? ??? main
? ??? test
? ??? test
? ??? java
? ? ??? com
? ? ??? github
? ? ??? xyz
? ? ??? proj
? ? ??? MainTest.java
? ? ??? TestBase.java
? ??? resources
? ??? abcd.txt
??? target
??? test-classes
??? com
??? abcd.txt
Run Code Online (Sandbox Code Playgroud)
// in MainClass.java
this.getClass.getResource("/") -> "~/proj_dir/target/test-classes/"
this.getClass.getResource(".") -> "~/proj_dir/target/test-classes/com/github/xyz/proj/"
Thread.currentThread().getContextClassLoader().getResources(".") -> "~/proj_dir/target/test-classes/"
Thread.currentThread().getContextClassLoader().getResources("/") -> null
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
301236 次 |
| 最近记录: |