|
How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 3:14 AM
|
|
|
Referencing a file with the absolute path or relative to the current working directory works flawlessly. what if i don't know the path during compile time but only during runtime? i know the fileName (without path) during runtime, but don't know where it is located. I just know that it is in the CLASSPATH. SO i tried these two ways to get the InputStream for a fileName:
try {
URL url = IOUtils.class.getResource(fileName);
result = url.openStream();
} catch (Exception e) { out(e); }
//try to load from CLASSPATH:
if (result == null) {
try {
URLClassLoader cl = (URLClassLoader) IOUtils.class.getClassLoader();
URL url = cl.findResource(fileName);
result = url.openStream();
} catch (Exception e) { out(e); }
}
but both don't find the file, even though the file is in the CLASSPATH (also checked correct spelling). is there another way to retrieve the File or InputStream object to a file in the CLASSPATH?
|
|
|
Re: How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 3:34 AM (reply 1 of 5)
|
|
|
Hallo,
yes, this is sometimes a difficult problem. I have sweated blood doing this as well. I think that the bast way is probably:
URL url = ClassLoader.getSystemResource(fileName);
|
|
|
Re: How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 4:11 AM (reply 2 of 5)
|
|
|
nope that doesn't work. but i wrote my own method that loads the file from the classpath (which works :-) :
/**
* Get CLASSPATH entries.
*
* @return List of all entries in the current CLASSPATH.
*/
public static List getClassPath() {
List result = new ArrayList();
String classPath = System.getProperty("java.class.path");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < classPath.length(); i++) { //for each character
if (classPath.charAt(i) == ';') {
result.add(sb.toString());
sb.setLength(0);
} else {
sb.append(classPath.charAt(i));
}
}//next character
if (!sb.equals("")) {
result.add(sb.toString());
}
return result;
}//getClassPath()
/**
* Try to open a valid InputStream from various sources (CLASSPATH, Filesystem, Jar, etc.)
*
* @param fileName Name of file to open.
* @return InputStream or null if not found/not possible.
*/
public InputStream openInputStream(String fileName) {
InputStream result = null;
if (fileName != null) {
//try to load from URL:
try {
URL url = this.class.getResource(fileName);
result = url.openStream();
} catch (Exception e) { /* ignore */ }
//try to get from system:
if (result == null) {
try {
URL url = ClassLoader.getSystemResource(fileName);
result = url.openStream();
} catch (Exception e) { /* ignore */ }
}
//try to load from CLASSPATH (JDK 1.2):
if (result == null) {
try {
URLClassLoader cl = (URLClassLoader) IOUtils.class.getClassLoader();
URL url = cl.findResource(fileName);
result = url.openStream();
} catch (Exception e) { /* ignore */ }
}
//try to load from CLASSPATH (JDK 1.1):
if (result == null) {
try {
ClassLoader cl = this.class.getClassLoader();
result = cl.getResourceAsStream(fileName);
} catch (Exception e) {
//ignore
}
}
//try to load from current working directory:
if (result == null) {
try {
result = new FileInputStream(fileName);
} catch (Exception e) { /* ignore */ }
}
//try to load from user home directory:
if (result == null) {
try {
result = new FileInputStream(System.getProperty("user.dir") + File.separatorChar + fileName);
} catch (Exception e) { /* ignore */ }
}
//try to load from CLASSPATH:
if (result == null) {
try {
List classPath = getClassPath();
Iterator iterator = classPath.iterator();
while (iterator.hasNext()) {
String classPathFileName = (String) iterator.next();
File file = new File(classPathFileName);
if (file.exists()) {
if (file.isFile()) {
//check if CLASSPATH file is the file we're looking for:
if (file.getName().equals(fileName)) {
result = new FileInputStream(classPathFileName);
break;
} else {
//perhaps the current file is an archive containing the file:
ZipInputStream zis = new ZipInputStream(new FileInputStream(classPathFileName));
ZipEntry ze = null;
for (ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
if (ze.getName().equals(fileName.replace(File.separatorChar, '/'))) {
result = new DataInputStream(zis);
break;
}
}//next ZipEntry
}
} else if (file.isDirectory()) {
// if class path is directory, check if file found along that path
file = new File(classPathFileName + File.separatorChar + fileName);
if (file.isFile()) {
result = new DataInputStream(new FileInputStream(file));
break;
}
}
}//else: file does not exist
}//next CLASSPATH entry
} catch (Exception e) { /* ignore */ }
}
}//else: input unavailable
return result;
}//openInputStream()
|
|
edsonw
Posts:3,055
Registered: 18/06/98
|
Re: How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 4:16 AM (reply 3 of 5)
|
|
|
Great!
But replace
if (classPath.charAt(i) == ';') {
by something that is more operating-system independent, like comparing with a variable that holds the value of System.getProperty("path.separator").
|
|
|
Re: How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 4:19 AM (reply 4 of 5)
|
|
|
I' m using
Util.class.getClassLoader().getResourceAsStream("myFile.txt");
and it works.
|
|
|
Re: How to get File/InputStream from a file in CLASSPATH? Nov 26, 2003 5:22 AM (reply 5 of 5)
|
|
|
even better:
/**
* Get CLASSPATH entries.
*
* @return List of all entries in the current CLASSPATH.
*/
public static List getClassPath() {
List result = new ArrayList();
String classPath = System.getProperty("java.class.path");
StringBuffer sb = new StringBuffer();
char pathSeparator = ';'; //default
String ps = System.getProperty("path.separator");
if (ps != null && ps.length() > 0) {
pathSeparator = ps.charAt(0);
}
StringCharacterIterator sci = new StringCharacterIterator(classPath);
char c = sci.first();
while (c != CharacterIterator.DONE) {
if (c == pathSeparator) {
result.add(sb.toString());
sb.setLength(0);
} else {
sb.append(c);
}
c = sci.next();
}//next character
if (!sb.equals("")) {
result.add(sb.toString());
}
return result;
}//getClassPath()
|