Mne*_*nth 105
如果要从应用程序内部读取该文件,请使用:
InputStream input = getClass().getResourceAsStream("/classpath/to/my/file");
Run Code Online (Sandbox Code Playgroud)
路径以"/"开头,但这不是文件系统中的路径,而是在类路径中.因此,如果您的文件位于类路径"org.xml"并且名为myxml.xml,则您的路径看起来像"/org/xml/myxml.xml".
InputStream读取文件的内容.如果需要,您可以将其包装到Reader中.
我希望有所帮助.
小智 53
啊,这是我最喜欢的科目之一.基本上有两种方法可以通过类路径加载资源:
Class.getResourceAsStream(resource)
Run Code Online (Sandbox Code Playgroud)
和
ClassLoader.getResourceAsStream(resource)
Run Code Online (Sandbox Code Playgroud)
(还有其他方法涉及以类似的方式获取资源的URL,然后打开与它的连接,但这是两种直接的方式).
在修改资源名称之后,第一种方法实际委托给第二种方法.基本上有两种资源名称:绝对(例如"/ path/to/resource/resource")和relative(例如"resource").绝对路径以"/"开头.
这是一个应该说明的例子.考虑一个类com.example.A.考虑两个资源,一个位于/ com/example/nested,另一个位于/ path,位于类路径中.以下程序显示了访问这两种资源的九种可能方法:
package com.example;
public class A {
public static void main(String args[]) {
// Class.getResourceAsStream
Object resource = A.class.getResourceAsStream("nested");
System.out.println("1: A.class nested=" + resource);
resource = A.class.getResourceAsStream("/com/example/nested");
System.out.println("2: A.class /com/example/nested=" + resource);
resource = A.class.getResourceAsStream("top");
System.out.println("3: A.class top=" + resource);
resource = A.class.getResourceAsStream("/top");
System.out.println("4: A.class /top=" + resource);
// ClassLoader.getResourceAsStream
ClassLoader cl = A.class.getClassLoader();
resource = cl.getResourceAsStream("nested");
System.out.println("5: cl nested=" + resource);
resource = cl.getResourceAsStream("/com/example/nested");
System.out.println("6: cl /com/example/nested=" + resource);
resource = cl.getResourceAsStream("com/example/nested");
System.out.println("7: cl com/example/nested=" + resource);
resource = cl.getResourceAsStream("top");
System.out.println("8: cl top=" + resource);
resource = cl.getResourceAsStream("/top");
System.out.println("9: cl /top=" + resource);
}
}
该程序的输出是:
1: A.class nested=java.io.BufferedInputStream@19821f 2: A.class /com/example/nested=java.io.BufferedInputStream@addbf1 3: A.class top=null 4: A.class /top=java.io.BufferedInputStream@42e816 5: cl nested=null 6: cl /com/example/nested=null 7: cl com/example/nested=java.io.BufferedInputStream@9304b1 8: cl top=java.io.BufferedInputStream@190d11 9: cl /top=null
大多数事情做你期望的事情.Case-3失败,因为类相对解析是关于Class的,所以"top"表示"/ com/example/top",但"/ top"表示它所说的内容.
Case-5失败,因为类加载器相对解析是关于类加载器的.但是,出乎意料的是Case-6也失败了:有人可能会期望"/ com/example/nested"正确解析.要通过类加载器访问嵌套资源,您需要使用Case-7,即嵌套路径相对于类加载器的根.同样Case-9失败了,但是Case-8失败了.
记住:对于java.lang.Class,getResourceAsStream()会委托给类加载器:
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
所以这是resolveName()的行为很重要.
最后,由于类加载器的行为加载了本质上控制getResourceAsStream()的类,并且类加载器通常是自定义加载器,因此资源加载规则可能更复杂.例如,对于Web应用程序,在Web应用程序的上下文中从WEB-INF/classes或WEB-INF/lib加载,但不从其他隔离的Web应用程序加载.此外,行为良好的类加载器委托给父类,因此使用此机制可能无法访问类路径中的重复资源.
小智 8
首先检查你的类加载器.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = Class.class.getClassLoader();
}
classLoader.getResourceAsStream("xmlFileNameInJarFile.xml");
// xml file location at xxx.jar
// + folder
// + folder
// xmlFileNameInJarFile.xml
Run Code Online (Sandbox Code Playgroud)
小智 5
JAR 基本上是一个 ZIP 文件,因此也应将其视为 ZIP 文件。下面包含一个有关如何从 WAR 文件(也将其视为 ZIP 文件)中提取一个文件并输出字符串内容的示例。对于二进制文件,您需要修改提取过程,但有很多相关示例。
public static void main(String args[]) {
String relativeFilePath = "style/someCSSFile.css";
String zipFilePath = "/someDirectory/someWarFile.war";
String contents = readZipFile(zipFilePath,relativeFilePath);
System.out.println(contents);
}
public static String readZipFile(String zipFilePath, String relativeFilePath) {
try {
ZipFile zipFile = new ZipFile(zipFilePath);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
// if the entry is not directory and matches relative file then extract it
if (!entry.isDirectory() && entry.getName().equals(relativeFilePath)) {
BufferedInputStream bis = new BufferedInputStream(
zipFile.getInputStream(entry));
// Read the file
// With Apache Commons I/O
String fileContentsStr = IOUtils.toString(bis, "UTF-8");
// With Guava
//String fileContentsStr = new String(ByteStreams.toByteArray(bis),Charsets.UTF_8);
// close the input stream.
bis.close();
return fileContentsStr;
} else {
continue;
}
}
} catch (IOException e) {
logger.error("IOError :" + e);
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,我使用 Apache Commons I/O,如果您使用 Maven,则这里是依赖项:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
133470 次 |
| 最近记录: |