How do I access the content of folders inside a jar file?
I need to take a look at the names of files inside a specific package. Currently, I'm doing the following:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL packageUrl = loader.getResource(getPackage().replace('.', '/'));
File packageDir = new File(packageUrl.getFile());
// Work with the files inside the directory
This actually works just fine in Eclipse, sinc开发者_如何学JAVAe it doesn't package my application by default. When I run it from a jar file, however, I get a NullPointerException
on packageUrl
.
So, how do I obtain a list of the contents of a package that's inside a jar? My research suggested using getResourceAsStream
, but I'm not quite sure how to explore a directory with an InputStream
, if that's even possible.
You could get path to the jar file and open it with ZipInputStream list all the files inside that jar.
To know the path of the running jar, try using:
InputStream in = MyClass
.class
.getProtectionDomain()
.getCodeSource()
.getLocation()
.openStream();
See also: How do I list the files inside a JAR file?
update
I've compiled an ran your solution and works perfect:
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
You can use a JarInputStream
to read the contents of a jar file. You'll iterate over the JarEntry
objects returned by getNextJarEntry()
which have a getName()
. If you don't care about any of the jar-specific metadata, such a code-signers or additional Manifest entries, you can stick with the ZipInputStream
superclass.
精彩评论