Às vezes, os recursos embutidos em seu .jar precisam ser extraídos para o sistema de arquivos do cliente. Exemplos disso são executáveis e fontes (o SWT só pode carregar fontes do sistema de arquivos local).
Aqui está uma classe que irá extrair arquivos de dentro de seu jar, colocá-los em um diretório temporário, retornar o caminho do arquivo temporário e até mesmo remover os arquivos após a saída do Java VirtualMachine.
Para usar a classe, algo assim funciona:
String filePath = ResourceManager.extract("/com/dennisskinner/testapp/img/face.png");
Observe que o uso de caminhos absolutos é muito necessário por motivos de sanidade, no entanto, você pode usar um caminho relativo do local do ResourceManager, mas isso não é recomendado.
Finalmente, aqui está o 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;
}
}
}