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()
的调用返回什么?该方法是否返回相对于调用类的位置?我要查找的条目位于不同的包树上,因此这可能是问题所在。