Tuesday, October 19, 2010

Reading from jar file from classpath

I had a recent issue with "read all the files in folder from within the jar file that is in the class path". The standard solution is generate a resources file (in this case include all the files) and set it to a known location in the jar file. Then access the resource file, read the names and load the files from the stream.

I did it this way:

public class ZipFileUtil {

/**
* Lowercase extension names for zip or zipish files.
*/
private static final String[] zipExtensions = { ".zip", ".jar" };

/**
* Name of system property for java class path.
*/
private static final String CLASS_PATH_PROPERTY_NAME = "java.class.path";

/**
* Search the class path for a file name.
*
* This is slower if not case sensitive.
*
* @param fileName the file name
* @param caseSensitive the match for file name will be case sensitive
* @return a File or null if not found or if this isn't a zip (or zipish) file.
*/
public static File getFileFromJar(String fileName, final boolean caseSensitive) {

if (!isJarFile(fileName)) {
return null;
}

fileName = fileName.trim();

File rVal = null;

final String fullPath = System.getProperties().getProperty(CLASS_PATH_PROPERTY_NAME);
final String[] jars = fullPath.split(File.pathSeparator);
if (jars != null) {
for (String jarName : jars) {
jarName = jarName.trim();
if (jarName.endsWith(fileName) || (!caseSensitive && jarName.toLowerCase().endsWith(fileName.toLowerCase()))) {
return new File(jarName);
}
}
}

return rVal;
}

/**
* List all the file names contained in a jar/zip file.
*
* @param jarFile the jar/zip file to search
* @param target pattern to match (no wildcards)
* @return list of strings that are relative filenames that match the target pattern or null if this isn't a zip (or zipish) file.
* @throws IOException if an exception occurs
*/
public static List listMatchingContents(final File jarFile, final String target) throws IOException {

if (!isJarFile(jarFile)) {
return null;
}

final List rVal = new ArrayList();

ZipInputStream zis = new ZipInputStream(new FileInputStream(jarFile));

for (ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
if (ze.getName().indexOf(target) > -1) {
rVal.add(ze.getName());
}
}

return rVal;
}

/**
* List all the file names contained in a jar/zip file.
*
* @param jarFilename the name of jar/zip file to search
* @param target pattern to match (no wildcards)
* @return list of strings that are relative filenames that match the target pattern or null if this isn't a zip (or zipish) file.
* @throws IOException if an exception occurs
*/
public static List listMatchingContents(final String jarFilename, final String target) throws IOException {
return listMatchingContents(new File(jarFilename), target);
}

/**
* Is this a zip file?.
*
* @param aFilename a file name
* @return true of false (true for yes it is a zipish file)
*/
public static boolean isJarFile(String aFilename) {
if (aFilename == null || aFilename.trim().length() == 0) {
return false;
}

aFilename = aFilename.trim().toLowerCase();
for (String anExtension : zipExtensions) {
if (aFilename.endsWith(anExtension)) {
return true;
}
}

return false;
}

/**
* Is this a zip file?.
*
* @param aFile a file
* @return true of false (true for yes it is a zipish file)
*/
public static boolean isJarFile(final File aFile) {
if (aFile == null) {
return false;
}

return isJarFile(aFile.getName());
}
}

1 comment:

Unknown said...

Also, it occurs to me that this blog is horrible at formating code