How to implement a universal file loader in Java?
This is what开发者_开发问答 I'm trying to do:
public String load(String path) {
//...
}
load("file:/tmp/foo.txt"); // loads by absolute file name
load("classpath:bar.txt"); // loads from classpath
I think it's possible to do with JDK, but can't find out how exactly.
I can think of two approaches:
Just write plain Java code to extract the "scheme" from those URI-like strings, and then dispatch to the different code to load the file in different ways.
Register a custom URL stream handler to deal with the "classpath" case and then use
URL.openStream()
to open the stream to read the object.
The package documentation for java.net has some information about how stream handlers are discovered.
From my libraries omino roundabout, the two methods you'll need... I need them everywhere. The resource reader is relative to a class, at least to know which jar to read. But the path can start with / to force it back to the top. Enjoy!
(You'll have to make our own top level wrapper to look for "file:" and "classpath:".)
see also http://code.google.com/p/omino-roundabout/
public static String readFile(String filePath)
{
File f = new File(filePath);
if (!f.exists())
return null;
String result = "";
try
{
FileReader in = new FileReader(f);
boolean doing = true;
char[] bunch = new char[10000];
int soFar = 0;
while (doing)
{
int got = in.read(bunch, 0, bunch.length);
if (got <= 0)
doing = false;
else
{
String k = new String(bunch, 0, got);
result += k;
soFar += got;
}
}
} catch (Exception e)
{
return null;
}
// Strip off the UTF-8 front, if present. We hate this. EF BB BF
// see http://stackoverflow.com/questions/4897876/reading-utf-8-bom-marker for example.
// Mysteriously, when I read those 3 chars, they come in as 212,170,248. Fine, empirically, I'll strip that, too.
if(result != null && result.length() >= 3)
{
int c0 = result.charAt(0);
int c1 = result.charAt(1);
int c2 = result.charAt(2);
boolean leadingBom = (c0 == 0xEF && c1 == 0xBB && c2 == 0xBF);
leadingBom |= (c0 == 212 && c1 == 170 && c2 == 248);
if(leadingBom)
result = result.substring(3);
}
// And because I'm a dictator, fix up the line feeds.
result = result.replaceAll("\\r\\n", "\n");
result = result.replaceAll("\\r","\n");
return result;
}
static public String readResource(Class<?> aClass,String srcResourcePath)
{
if(aClass == null || srcResourcePath==null || srcResourcePath.length() == 0)
return null;
StringBuffer resultB = new StringBuffer();
URL resourceURL = null;
try
{
resourceURL = aClass.getResource(srcResourcePath);
}
catch(Exception e) { /* leave result null */ }
if(resourceURL == null)
return null; // sorry.
try
{
InputStream is = resourceURL.openStream();
final int BLOCKSIZE = 13007;
byte[] bytes = new byte[BLOCKSIZE];
int bytesRead = 0;
while(bytesRead >= 0)
{
bytesRead = is.read(bytes);
if(bytesRead > 0)
{
char[] chars = new char[bytesRead];
for(int i = 0; i < bytesRead; i++)
chars[i] = (char)bytes[i];
resultB.append(chars);
}
}
}
catch(IOException e)
{
return null; // sorry
}
String result = resultB.toString();
return result;
}
(edit -- removed a stray reference to OmString, to keep it standalone here.)
精彩评论