Java 如何访问jar文件中文件夹的内容?
我需要查看特定包中的文件名。目前,我正在做以下工作:Java 如何访问jar文件中文件夹的内容?,java,jar,classloader,Java,Jar,Classloader,我需要查看特定包中的文件名。目前,我正在做以下工作: ClassLoader loader = Thread.currentThread().getContextClassLoader(); URL packageUrl = loader.getResource(getPackage().replace('.', '/')); File packageDir = new File(packageUrl.getFile()); // Work with the files inside the
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL packageUrl = loader.getResource(getPackage().replace('.', '/'));
File packageDir = new File(packageUrl.getFile());
// Work with the files inside the directory
这实际上在Eclipse中工作得很好,因为默认情况下它不会打包我的应用程序。然而,当我从jar文件运行它时,我在packageUrl
上得到一个NullPointerException
那么,如何获得一个jar中的包的内容列表呢?我的研究建议使用
getResourceAsStream
,但如果可能的话,我不太确定如何使用InputStream
浏览目录。您可以获得jar文件的路径,并使用ZipInputStream打开它,列出该jar中的所有文件
要知道正在运行的jar的路径,请尝试使用:
InputStream in = MyClass
.class
.getProtectionDomain()
.getCodeSource()
.getLocation()
.openStream();
另见:
更新
我已经编译了一个运行您的解决方案并运行良好:
C:\java\injar>dir
El volumen de la unidad C no tiene etiqueta.
El número de serie del volumen es: 22A8-203B
Directorio de C:\java\injar
21/02/2011 06:23 p.m. <DIR> .
21/02/2011 06:23 p.m. <DIR> ..
21/02/2011 06:23 p.m. 1,752 i18n.jar
21/02/2011 06:23 p.m. <DIR> src
21/02/2011 06:21 p.m. <DIR> x
C:\java\injar>jar -tf i18n.jar
META-INF/
META-INF/MANIFEST.MF
I18n.class
x/
x/y/
x/y/z/
x/y/z/hola.txt
C:\java\injar>type src\I18n.java
import java.util.*;
import java.net.*;
import java.util.jar.*;
class I18n {
public static void main( String ... args ) {
getLocaleListFromJar();
}
private static List<Locale> getLocaleListFromJar() {
List<Locale> locales = new ArrayList<Locale>();
try {
URL packageUrl = I18n.class.getProtectionDomain().getCodeSource().getLocation();
JarInputStream jar = new JarInputStream(packageUrl.openStream());
while (true) {
JarEntry entry = jar.getNextJarEntry();
if (entry == null) {
System.out.println( "entry was null ");
break;
}
String name = entry.getName();
System.out.println( "found : " +name );
/*if (resourceBundlePattern.matcher(name).matches()) {
addLocaleFromResourceBundle(name, locales);
}*/
}
} catch (Exception e) {
System.err.println(e);
return null;
//return getLocaleListFromFile(); // File based implementation in case resources are not in jar
}
return locales;
}
}
C:\java\injar>java -jar i18n.jar
found : I18n.class
found : x/
found : x/y/
found : x/y/z/
found : x/y/z/hola.txt
entry was null
C:\java\injar>dir
这本书没有什么特别之处。
埃尔努梅罗系列卷es:22A8-203B
C:\java\injar目录
2011年2月21日下午6:23。
2011年2月21日下午6:23。。
2011年2月21日下午6:23 1752年1月18日
2011年2月21日06:23下午src
2011年2月21日06时21分
C:\java\injar>jar-tf i18n.jar
META-INF/
META-INF/MANIFEST.MF
I18n.类
x/
x/y/
x/y/z/
x/y/z/hola.txt
C:\java\injar>类型src\I18n.java
导入java.util.*;
导入java.net。*;
导入java.util.jar.*;
I18n类{
公共静态void main(字符串…参数){
getLocaleListFromJar();
}
私有静态列表getLocaleListFromJar(){
List locales=new ArrayList();
试一试{
URL packageUrl=I18n.class.getProtectionDomain().getCodeSource().getLocation();
JarInputStream jar=新的JarInputStream(packageUrl.openStream());
while(true){
JarEntry=jar.getNextJarEntry();
if(条目==null){
System.out.println(“条目为空”);
打破
}
String name=entry.getName();
System.out.println(“找到:+名称);
/*if(resourceBundlePattern.matcher(name.matches()){
addLocaleFromResourceBundle(名称、区域设置);
}*/
}
}捕获(例外e){
系统错误println(e);
返回null;
//返回getLocaleListFromFile();//如果资源不在jar中,则返回基于文件的实现
}
返回地点;
}
}
C:\java\injar>java-jar i18n.jar
发现:I18n.class
发现:x/
发现:x/y/
发现:x/y/z/
找到:x/y/z/hola.txt
条目为空
您可以使用读取jar文件的内容。您将迭代getNextJarEntry()
返回的JarEntry
对象,该对象具有getName()
。如果您不关心任何特定于jar的元数据,例如代码签名者或其他清单条目,您可以坚持使用ZipInputStream
超类。+1对于特定于jar
的类,我将来可能需要它。我尝试过,但getNextEntry()
似乎总是返回null
getLocation()
返回rsrc:。/
。有什么问题吗?顺便说一下,我正在尝试从我的应用程序自己的jar中读取文件。。。我想我应该提一下。你们有我们可以看到的样品吗?我使用了前面提到的代码来加载jar中的所有图像,效果很好:查看它。与此同时,你注意到了吗?是 啊我的实现基于这个答案,但做得不同。我错过什么了吗?真奇怪。对getLocation()
的调用返回什么?该方法是否返回相对于调用类的位置?我要查找的条目位于不同的包树上,因此这可能是问题所在。