Accessing a File Inside a .Jar File

Access file in jar file?

You could use something like this:

InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileFromJarFile);

If foo.txt was in the root of your JAR file, you'd use:

InputStream is = this.getClass().getClassLoader().getResourceAsStream("foo.txt");

assumes the class is in the same JAR file as the resource, I believe.

Reading a resource file from within jar

Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:

try (InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
// Use resource
}

As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.

The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.

This is explained well by the answers to:

  • How do I read a resource file from a Java jar file?
  • Java Jar file: use resource errors: URI is not hierarchical

Accessing a file inside a .jar file

When your resourse is in JAR file, it's not a File anymore. A File is only a physical file on the filesystem.
Solution: use getResourceAsStream. Something like this:

new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/resources/" + filename)))

Accessing files inside a jar file

That's because the file is inside the JAR and is no longer accessible on the file system - using a FileInputStream is still using files.

You need to treat it as a resource instead and get an InputStream from that, then it will work both when packaged as a JAR and when not.

h = t.getResponseHeaders();
os = t.getResponseBody();

// Get an URL to the file
URL url = getClass().getResource("GreetingText.html");

// Open the stream and read the contents into a byte array
byte[] bytes;
try(InputStream in = url.openStream();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) > 0) {
bytes.write(buffer, 0, read);
}
bytes = out.toByteArray();
}

h.add("Content-Type", "text/html");
t.sendResponseHeaders(200, bytes.length);
os.write(bytes, 0, bytes.length);
os.close();

Place the file on your classpath, if it's in another package you need to prefix the path with /path/to/file, so if you put it in the directory html at the root of your classpath you will have to use "/html/GreetingText.html".

How to list the files inside a JAR file?

CodeSource src = MyClass.class.getProtectionDomain().getCodeSource();
if (src != null) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream(jar.openStream());
while(true) {
ZipEntry e = zip.getNextEntry();
if (e == null)
break;
String name = e.getName();
if (name.startsWith("path/to/your/dir/")) {
/* Do something with this entry. */
...
}
}
}
else {
/* Fail... */
}

Note that in Java 7, you can create a FileSystem from the JAR (zip) file, and then use NIO's directory walking and filtering mechanisms to search through it. This would make it easier to write code that handles JARs and "exploded" directories.



Related Topics



Leave a reply



Submit