Resource Extraction from Jar to Local File System
Sometimes resources embedded inside your .jar need to be extracted to the client's file system. Examples of this are executables and fonts (SWT can only load fonts from the local file system).
Here's a class that will extract files from inside your jar, place them in a temp directory, return the temporary file's path, and even remove the files after the Java VirtualMachine exits.
To use the class, something like this works:
String filePath = ResourceManager.extract("/com/dennisskinner/testapp/img/face.png");
Please note, that using absolute paths is pretty much required for sanity reasons, however you could use a relative path from the ResourceManager's location, but this is not recommended.
Finally, here's the ResourceManager.
import javax.swing.*;
import java.io.*;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.function.BiConsumer;
public class ResourceManager {
// Stores paths to files with the global jarFilePath as the key
private static Hashtable<String, String> fileCache = new Hashtable<String, String>();
/**
* Extract the specified resource from inside the jar to the local file system.
* @param jarFilePath absolute path to the resource
* @return full file system path if file successfully extracted, else null on error
*/
public static String extract(String jarFilePath){
if(jarFilePath == null)
return null;
// See if we already have the file
if(fileCache.contains(jarFilePath))
return fileCache.get(jarFilePath);
// Alright, we don't have the file, let's extract it
try {
// Read the file we're looking for
InputStream fileStream = ResourceManager.class.getResourceAsStream(jarFilePath);
// Was the resource found?
if(fileStream == null)
return null;
// Grab the file name
String[] chopped = jarFilePath.split("\\/");
String fileName = chopped[chopped.length-1];
// Create our temp file (first param is just random bits)
File tempFile = File.createTempFile("asdf", fileName);
// Set this file to be deleted on VM exit
tempFile.deleteOnExit();
// Create an output stream to barf to the temp file
OutputStream out = new FileOutputStream(tempFile);
// Write the file to the temp file
byte[] buffer = new byte[1024];
int len = fileStream.read(buffer);
while (len != -1) {
out.write(buffer, 0, len);
len = fileStream.read(buffer);
}
// Store this file in the cache list
fileCache.put(jarFilePath, tempFile.getAbsolutePath());
// Close the streams
fileStream.close();
out.close();
// Return the path of this sweet new file
return tempFile.getAbsolutePath();
} catch (IOException e) {
return null;
}
}
}
Written by Dennis Skinner
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Jar
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#