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

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

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

我使用以下代码来获取 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不适用,我可以使用哪些替代方案?

PS我只需要访问两个文件(每个<1MB),所以我不认为我可能需要使用数据库来包含它们, 如此线程中的减号 所示 。

文件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(); } 

要读取文件:

 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或类似的东西。 您绝对不希望将容器的临时目录用于真正临时文件以外的任何内容,可以在重新部署时删除等。

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

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

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

除非出于某种原因你真的需要java.io.File ,否则从classpath加载文件并不担心它来自何处。

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

我使用Spring Resource组件来获取我的文件路径 ,如test.arff所示( 注意 test.arffwar部署之前位于root/src ):

 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. 如果用于获取文件不要混淆,那么这两个文件路径是相同的。

Interesting Posts