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

And*_*Evt 2 java resources jar file

我正在尝试制作一个简单的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");
Run Code Online (Sandbox Code Playgroud)

对于index.html我变成:Resources: /www/index.html Result code: 200- >一切正常.

但是当我这样做的时候:

private static final String DEFAULT_FILES_DIR = "D:/.../.../.../www"; // absolute pass;
....
....
Run Code Online (Sandbox Code Playgroud)

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

它可以是什么?

Ps我试图放,private static final String DEFAULT_FILES_DIR = "D:\\...\\...\\...\\www";但它不会工作!))))

Jas*_*n C 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.
    }
    
    Run Code Online (Sandbox Code Playgroud)

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