【问题标题】:Loading resource from JAR or file system with getResourceAsStream使用 getResourceAsStream 从 JAR 或文件系统加载资源
【发布时间】:2013-11-16 20:18:36
【问题描述】:

我正在尝试制作一个简单的 Http 服务器。

但我有一个小问题。

如果我的 /www 目录在 .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 -> 找不到文件。

可能是什么?

附:我尝试输入private static final String DEFAULT_FILES_DIR = "D:\\...\\...\\...\\www";,但它不起作用!))))

【问题讨论】:

  • 您能告诉我们您是如何尝试访问此资源的吗?此外,您的方法的名称暗示它应该返回一个 URL,但“D:\...”不是一个有效的 URL。文件 URL 以方案“file://”开头。您可能希望使用java.net.URL 而不是String 来强制执行正确的语义。
  • getURLFromHeader() 返回 String(url),默认 dir_url + file_url。这个url 采用另一种方法,而不是:InputStream stream = HttpServer.class.getResourceAsStream(**url**); 并检查:int code = (stream != null) ? 200 : 404;。或者你想看什么?如果有必要,我可以显示完整的代码。

标签: java file jar resources


【解决方案1】:

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

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

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

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

    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() 加载本地文件资源,您必须以您认为合适的任何方式以不同方式处理这两种情况。

【讨论】:

    猜你喜欢
    • 2012-02-10
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2014-10-11
    • 1970-01-01
    • 2015-11-16
    相关资源
    最近更新 更多