2011-08-20 48 views
2

这就是我想要做的事:如何在Java中实现通用文件加载器?

public String load(String path) { 
    //... 
} 
load("file:/tmp/foo.txt"); // loads by absolute file name 
load("classpath:bar.txt"); // loads from classpath 

我认为这是可能与JDK做的,但不能找出究竟是如何。

回答

3

我能想到的两种方法:

  • 只需编写普通的Java代码,从这些类似URI的字符串中提取“scheme”,然后分派到不同的代码以不同的方式加载文件。

  • 注册一个自定义URL流处理程序来处理“classpath”情况,然后使用URL.openStream()来打开该流来读取该对象。

java.net的包文档包含有关如何发现流处理程序的一些信息。

-1

从我的图书馆omino环岛,你需要的两种方法...我需要他们无处不在。资源阅读器是相对于一个类的,至少要知道要读哪个jar。但是,路径可以以/开头,强制回到顶端。请享用!

(你必须使自己的顶级包装,以寻找“文件”和“类路径”)

又见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; 
} 

(编辑 - 移除流浪参考OmString,以保持其独立位置在这里)

+0

使用'FileReader'或任何使用默认字符编码的东西很少是个好主意。你对关于Unicode BOM的奇怪行为的评论应该暗示你没有正确处理编码。另外,为什么这两个相当长的方法的名称听起来像是做类似的事情,却没有共同的逻辑?你可能想要考虑让它们都创建一个'InputStream',然后它们传递给一个通用的专用辅助方法。 –

+0

Hi @Laurence - 感谢您的期待,并且您的评论已被好评和赞赏。感谢编码指针。关于共享内部帮助器方法的说明很有意义。他们为什么现在这样?他们在不同的时间写作,使用量很大,而且,直到一次测试失败时,它就不在我的掌握之中。 –