jar
之一中。如何读取jar
中包含的任何文件?#1 楼
如果要从应用程序内部读取该文件,请使用:InputStream input = getClass().getResourceAsStream("/classpath/to/my/file");
路径以“ /”开头,但不是文件系统中的路径,但是在你的classpath中。因此,如果您的文件位于类路径“ org.xml”中,并且名为myxml.xml,则您的路径类似于“ /org/xml/myxml.xml”。
InputStream读取文件的内容。如果需要,可以将其包装到阅读器中。
希望对您有所帮助。
#2 楼
啊,这是我最喜欢的科目之一。基本上有两种方法可以通过类路径加载资源: Class.getResourceAsStream(resource)
和
ClassLoader.getResourceAsStream(resource)
(还有其他方法可以获取资源的URL以类似的方式,然后打开到它的连接,但这是两种直接方式。
第一种方法实际上是在修改资源名称之后委托给第二种方法。资源名称本质上有两种:绝对名称(例如“ / path / to / resource / resource”)和相对名称(例如“ resource”)。绝对路径以“ /”开头。
这是一个例子,应该说明。考虑类com.example.A。考虑两个资源,一个位于类路径中的/ com / example / nested,另一个位于/ top。以下程序显示了访问两种资源的九种可能方法:
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失败是因为类相对于类是相对于类的,所以“ 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 / class或WEB-INF / lib加载,但不能从隔离的其他Web应用程序中加载。此外,行为良好的类加载器还会委派给父级,这样,使用此机制可能无法访问类路径中的重复资源。
评论
这基本上与我给出的答案相同,但更详细地解释了。 +1
–Mnementh
10年8月2日在10:52
这是提到的resolveName方法:gist.github.com/briangordon/5374626
–布赖恩·戈登(Brian Gordon)
13年4月12日在19:51
#3 楼
首先检查您的类加载器。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
#4 楼
JAR基本上是一个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;
}
在此示例中,我使用的是Apache Commons I / O,如果您使用的是Maven,则依赖项为:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
#5 楼
为了完整起见,Jython邮件列表上最近出现了一个问题,其中的答案之一就是与此线程相关。问题是如何从.js文件中调用.jar文件中包含的Python脚本。在Jython中,建议的答案如下(使用“ InputStream”,如以上答案之一所述:
PythonInterpreter.execfile(InputStream)
评论
参见stackoverflow.com/questions/16842306如果要从jar中的目录中读取文件,其中包含文件的任何编号,请参见Stackoverflow-Link