当我正在使用的第三方库尝试访问文件时,我收到“错误打开...文件...(没有这样的文件或目录)”即使我知道文件在战争。我已经尝试了打包(.war)和“爆炸”(目录)部署,文件肯定在那里。我也尝试过设置完全权限。它是在Unix(Ubuntu)上。文件是war / dict / index.sense,错误是“dict / index.sense(没有这样的文件或目录)”。
它在我的Windows计算机上运行时可以作为Eclipse的GWT应用程序在托管模式下运行,而不是在我将它传输到Unix机器进行部署时。
我的问题是:有没有人经历过这种情况和/或我应该考虑相对路径的差异,即在战争中相对文件访问的根路径是什么?
答案 0 :(得分:8)
在读取资源时,不应该依赖文件IO中的相对路径。工作目录取决于应用程序的启动方式。你完全没有控制权。始终在文件IO中使用绝对路径。
正常方法是:
将资源放在类路径中或将其路径添加到类路径中。然后您可以通过类加载器获取它,如下所示:
String classPathLocation = "filename.ext";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream(classPathLocation);
// ...
请注意如何获取类加载器和资源。你不应该从当前的类中获取它,如getClass().getResourceAsStream()
。在WAR中,可能存在多个类加载器的方法。当前类的类加载器可能不知道所需的资源本身,即上下文。
将资源放在webcontent中(WEB-INF
文件夹所在的位置以及所有其他公共Web资源)。然后你可以获得如下的绝对路径,你可以继续在通常的文件IO代码中使用它:
String relativeWebPath = "/filename.ext";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
InputStream input = new FileInputStream(absoluteDiskPath);
// ...
请注意,这只适用于展开WAR的情况,否则只会返回null
。
答案 1 :(得分:0)
我欠BalusC的答案,但由于我起初并不是真的理解它,所以我简化了它:
工作目录(相对路径的起点)取决于应用程序的启动方式,因此您无法真正控制它。幸运的是,有一种方法可以获取Web应用程序根目录中任何内容的绝对路径,如下所示:
getServletContext().getRealPath("pathToAnyFileInYourWebAppDocumentRoot.ext")
(这给出了一个字符串)
这就是你要做的一切。不幸的是,这仅在您的应用程序部署为目录时有效,而不是作为.war文件(将返回null
)。
(参见BalusC的另一种答案,以及答案的来源)。