战争webapp中的Tomcat服务器绝对文件访问

时间:2013-12-05 15:22:50

标签: java spring tomcat file-io absolute-path

我有一个Spring webapp,其.war文件已上传到Tomcat服务器。大多数基本功能都按预期工作 - 页面视图和表单提交。

我现在的问题是我的webapp需要读取和写入文件,我无法知道如何实现这一点(文件I / O返回java.lang.NullPointerException)。

我使用code to get the absolute path of a given file建议的以下Titi Wangsa Bin Damhore来了解相对于服务器的路径:

HttpSession session = request.getSession();
ServletContext sc = session.getServletContext();
String file = sc.getRealPath("src/test.arff");
logger.info("File path: " + file);

这是输出路径:

/home/username/tomcat/webapps/appname/src/test.arff

但是当我通过WinSCP检查文件目录时,文件的实际路径为:

/home/username/tomcat/webapps/appname/WEB-INF/classes/test.arff

以下是我的问题

  1. 如何将这些路径转换为C:/Users/Workspace/appname/src/test.arff(我本地机器中的原始路径完美运行)?它的服务器是Apache Tomcat 6.0.35Apache Tomcat 6.0.35
  2. 为什么代码返回的路径与实际路径不同?
  3. 如果文件I / O不适用,我可以使用哪些替代方案?
  4. PS 我只需要访问两个文件(每个<1MB),所以我认为我可能不需要使用数据库来包含它们minusthis thread中的建议{3}}

    文件I / O

    下面是我用来访问我需要的文件的代码。

    BufferedWriter writer;
        try {
            URI uri = new URI("/test.arff");
            writer = new BufferedWriter(new FileWriter(
                calcModelService.getAbsolutePath() + uri));
    
            writer.write(data.toString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    

4 个答案:

答案 0 :(得分:3)

阅读文件:

ServletContext application = ...;
InputStream in = null;

try {
  in = application.getResourceAtStream("/WEB-INF/web.xml"); // example

  // read your file
} finally {
  if(null != in) try { in.close(); }
   catch (IOException ioe) { /* log this */ }
}

写文件:

ServletContext application = ...;
File tmpdir = (File)application.getAttribute("javax.servlet.context.tempdir");

if(null == tmpdir)
  throw new IllegalStateException("Container does not provide a temp dir"); // Or handle otherwise

File targetFile = new File(tmpDir, "my-temp-filename.txt");
BufferedWriter out = null;

try {
  out = new BufferedWriter(new FileWriter(targetFile));

  // write to output stream
} finally {
  if(null != out) try { out.close(); }
  catch (IOException ioe) { /* log this */ }
}

如果你不想使用servlet容器提供的tmpdir,那么你应该使用完全在servlet上下文的purvue之外的某个地方,比如/path/to/temporary/files或类似的东西。您绝对不希望将容器的临时目录用于除了可以在重新部署时删除的真正临时文件以外的任何内容。

答案 1 :(得分:2)

这是一场战争;你不读/写里面的文件。

阅读是微不足道的;将文件放在类路径上,并作为资源读取。

你不应该在Web应用程序内部编写,因为即使它不是战争,上下文中的内容也可能在重新部署期间消失,它可能只在一个服务器上你是聚集的,等等。文件写入应该在可配置的地方。

答案 2 :(得分:0)

除非出于某种原因您确实需要java.io.File,否则请从类路径加载文件,不要担心它来自何处。

getClass().getClassLoader().getResourceAsStream("test.arff")

答案 3 :(得分:0)

我按照Spring Resource component to get my file path的建议使用了yawn,这样{{strong>注意 test.arff位于root/src部署war之前):

Resource resource = new ClassPathResource("/test.arff");
String arffPathRaw = resource.getURI().toString(); // returns file:/path/to/file
String arffPath = arffPathRaw.replace("file:/", ""); // pure file path

接下来,我只是将arff连接到我想要的文件:

URI uri = new URI("test.arff");
BufferedWriter writer = new BufferedWriter(new FileWriter(
        arffPath + uri));

我直接在那里使用arffPath只是为了一个简单的例子,但我做了一个函数,所以它会更方便。

  1. 文件路径实际上是/home/username/tomcat/webapps/bosom/WEB-INF/classes/test.arff所以不要害怕使用它(就像我一样)因为它看起来不像C:/path/to/file lmao

  2. 如果用于获取文件,这两个文件路径是相同的。