使用getResourceAsStream从JAR或文件系统加载资源
我正在尝试创建一个简单的Http服务器。
I'm trying to make a simple Http server.
但我有一点问题。
如果我的 / www
目录是.jar文件编译,所有工作完美:
代码:
If my /www
dir is in .jar file compilation, all workse perfect:
code:
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");
我成为:资源:/www/index.html结果代码:200
- >一切正常。
for index.html I become: Resources: /www/index.html Result code: 200
-> all works.
但是当我这样做时:
private static final String DEFAULT_FILES_DIR = "D:/.../.../.../www"; // absolute pass;
....
....
服务器说没人 ,我不知道你不会对我说什么! =)
并输入:资源:D:/.../.../.../ www / index.html结果代码:404
- >找不到文件。
server says "No man, i don't know what are you wont from me"! =)
and type: Resources: D:/.../.../.../www/index.html Result code: 404
-> file not found.
它可以是什么?
Ps我试图把私有静态最终字符串DEFAULT_FILES_DIR =D:\\ ... \\ ... \\ ... \\\\;
但它不起作用!))))
P.s. I tried to put private static final String DEFAULT_FILES_DIR = "D:\\...\\...\\...\\www";
but it wouldn't work!))))
您正在使用类.getResourceAsStream()
加载资源。这使用类加载器加载资源,它只能加载当前类路径中的路径。它无法加载任意本地文件。
You are using Class.getResourceAsStream()
to load the resource. This uses the class loader to load the resource and it can only load paths inside the current class path. It can't load arbitrary local files.
您应该使用 Class.getResourceAsStream()
获取资源在类路径中,并使用基本的 FileInputStream
来获取文件系统中的资源。
What you should do is use Class.getResourceAsStream()
for resources in the class path, and use a basic FileInputStream
for resources in the file system.
你必须拥有一种区分两者的方法。具体如何实现这取决于您的要求。你有很多选择,一些是:
You will have to have a way to differentiate between the two. Exactly how you implement this depends on your requirements. You have many options, a few are:
- 尝试加载
getResourceAsStream()
,如果失败,请使用FileInputStream
。这有点草率但可能适合你。需要注意的是,如果资源路径无意中错误但与本地文件匹配,则当您打算加载资源时,可能会错误地加载本地文件。 - 处理以 D:作为档案。这也有点草率,可能会使其他位置或相关文件路径中的文件处理变得复杂,但它非常简单,可能适用于您的应用程序。
- 使用正确形成的
java.net.URL
,如果方案类型为file,则将其视为本地文件。 -
摘要此背后您根据提前知道的资源类型构建的一些资源加载器接口。例如(根据需要处理异常):
- Attempt to load with
getResourceAsStream()
, and if it fails, use aFileInputStream
. This is a bit sloppy but may work for you. The caveat is you run the risk of mistakenly loading a local file when you meant to load a resource if the resource path was inadvertently incorrect but matches a local file. - Treat strings that start with "D:" as a file. This is also a bit sloppy and could complicate handling of files in other locations or relative file paths, but it is very simple and may work for your application.
- Use a properly formed
java.net.URL
, and if the scheme type is "file", treat it as a local file. Abstract this behind some resource loader interface that you construct based on the type of the resource that you know ahead of time. For example (handle exceptions as you see fit):
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()
加载本地文件资源,你将不得不以不同的方式处理这两种情况适合。
You have a lot of choices but the take home point is: You cannot load local file resources with Class.getResourceAsStream()
and you will have to handle the two cases differently, in any way you see fit.