使用getResourceAsStream从JAR或文件系统加载资源

时间:2013-11-05 19:59:36

标签: java file jar resources

我正在尝试创建一个简单的Http服务器。

但我有一点问题。

如果我的/www dir在.jar文件编译中,所有工作都完美: 代码:

private static final String DEFAULT_FILES_DIR = "/www";
....
private String getURLFromHeader(String header) {
    //gettint url from header
    ....
    return DEFAULT_FILES_DIR + url;
}
....
System.out.println("Resources: " + url + "\n");
System.out.println("Result code: " + code + "\n");

对于index.html我变为:Resources: /www/index.html Result code: 200 - >一切都有效。

但是当我这样做的时候:

private static final String DEFAULT_FILES_DIR = "D:/.../.../.../www"; // absolute pass;
....
....

服务器说“没有男人,我不知道你不会对我有什么”! =) 并输入:Resources: D:/.../.../.../www/index.html Result code: 404 - >文件未找到。

它可以是什么?

P.S。我试图放private static final String DEFAULT_FILES_DIR = "D:\\...\\...\\...\\www";但它不起作用!))))

1 个答案:

答案 0 :(得分:8)

您正在使用Class.getResourceAsStream()加载资源。这使用类加载器加载资源,它只能加载当前类路径中的路径。它无法加载任意本地文件。

您应该使用Class.getResourceAsStream()作为类路径中的资源,并使用基本FileInputStream作为文件系统中的资源。

你必须要有办法区分这两者。具体如何实现这取决于您的要求。你有很多选择,其中一些是:

  • 尝试加载getResourceAsStream(),如果失败,请使用FileInputStream。这有点草率但可能适合你。需要注意的是,如果资源路径无意中错误但与本地文件匹配,那么当您打算加载资源时,您可能会错误地加载本地文件。
  • 将以“D:”开头的字符串视为文件。这也有点草率,可能会使处理其他位置或相关文件路径中的文件变得复杂,但它非常简单,可能适用于您的应用程序。
  • 使用格式正确的java.net.URL,如果方案类型为“file”,则将其视为本地文件。
  • 在您基于您提前知道的资源类型构建的一些资源加载器接口后面抽象这个。例如(根据您的需要处理异常):

    interface ResourceLoader { 
        public InputStream getInputStream (); 
    }
    
    class ClassResourceLoader implements ResourceLoader {
        private final String resource;
        public ClassResourceLoader (String resource) { 
            this.resource = resource; 
        }
        @Override public InputStream getInputStream () { 
            return HttpServer.class.getResourceAsStream(resource);
        } 
    }
    
    class FileResourceLoader implements ResourceLoader {
        private final String resource;
        public FileResourceLoader (String resource) { 
            this.resource = resource; 
        }
        @Override public InputStream getInputStream () { 
            try {
                return new FileInputStream(resource);
            } catch (Exception x) {
                return null; 
            }
        } 
    }
    
    private ResourceLoader getResourceLoaderFromHeader (String header) {
        return ...; // whatever is appropriate.
    }
    

您有很多选择,但主要观点是:您无法使用Class.getResourceAsStream()加载本地文件资源,您将不得不以您认为合适的任何方式处理这两种情况。