[英]Tomcat server absolute file access in war webapp
我有一個 Spring webapp,其.war
文件已上傳到 Tomcat 服務器。 大多數基本功能都按預期工作 - 頁面查看和表單提交。
我現在的問題是我的 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
這是我的問題:
C:/Users/Workspace/appname/src/test.arff
(我本地機器中完美運行的原始路徑)? 它的服務器是Apache Tomcat 6.0.35
和Apache Tomcat 6.0.35
。PS我只需要訪問兩個文件(每個< 1MB),所以我認為我可能不需要使用數據庫來包含它們,如本線程中的減號建議的那樣。
文件輸入/輸出
下面是我用來訪問我需要的文件的代碼。
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 上下文之外的地方,例如/path/to/temporary/files
或類似的東西。 您絕對不想將容器的臨時目錄用於除真正的臨時文件之外的任何內容,這些文件可以在重新部署時刪除等。
這是一場戰爭。 您不會在其中讀取/寫入文件。
讀取很簡單:將文件放在類路徑上,然后作為資源讀取。
無論如何,您不應該在 Web 應用程序中編寫代碼,因為即使它不是WAR,上下文中的內容也可能在重新部署期間消失,或者如果您是集群的,則它可能只在一台服務器上,等等。而是文件寫入應該存在於可配置的地方。
除非出於某種原因您確實需要java.io.File
,否則請從類路徑加載文件並且不要擔心它來自哪里。
getClass().getClassLoader().getResourceAsStream("test.arff")
我用了春天Resource
分量,讓我的文件路徑為所建議的哈欠是這樣的(注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
只是為了一個簡單的例子,但我做了一個函數,所以它會更方便。
文件路徑實際上是/home/username/tomcat/webapps/bosom/WEB-INF/classes/test.arff
所以不要害怕使用它(就像我一樣)只是因為它看起來不像C:/path/to/file
lmao
如果用於獲取文件,請不要混淆這兩個文件路徑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.