最近客戶現場的技術支持接連反饋了一個問題:導入數據的時候,上傳的excel會在服務器上生成一個臨時文件,而這個臨時文件都在 tomcat 的安裝目錄下,若是上傳次數比較多的話,就會致使tomcat安裝目錄下有多個臨時的excel文件,很不合理也不美觀,以下圖:java
接到這個問題,第一反應是 java.io.tmpdir 這個系統配置沒指定好,由於作上傳的時候,是經過 linux
System.getProperty("java.io.tmpdir");
這種方式來獲取臨時目錄,而後把文件放到臨時目錄裏去的,按說這些臨時文件都應該在 tomcat 安裝目錄下的 temp 文件夾裏,由於這個是tomcat的臨時目錄,但如今卻沒有,因此懷疑是 java.io.tmpdir 這個系統變量沒指定好。apache
以後就開始了各類查找資料,百度查完了查搜狗,搜狗查完了查Stack Overflow,但並無獲得想要的答案,全部的文件都是告訴你臨時文件目錄在哪,固然也查到了若是去設置這個 java.io.tmpdir ,經過下面的方式:tomcat
java -Djava.io.tmpdir=/path/to/tmpdir 服務器
但實際在linux服務器上執行的時候,發現這個命令根本沒法執行,查了 Stack Overflow 才知道,這個命令後面還須要跟一個有 main 方法的Java類才行,但這顯然是行不通的,也跟我想象中的設置java.io.temdir屬性的方式不同,只能接着查資料。編輯器
查了半天,也沒什麼收穫,問題始終沒解決,最後,打印了一下程序執行時取到的 java.io.tmpdir 對應的目錄,才知道問題在哪,代碼以下:spa
先看一下打印結果:3d
能夠看出來,程序運行時取到的 java.io.tmpdir 的值是徹底正確的,對應的就是tomcat安裝目錄下的 temp 文件夾日誌
再看日誌打印下面的代碼,原來我在拼接文件完整路徑的時候,在臨時目錄和文件名之間沒有加 / ,致使拼接出來的臨時文件是這樣的地址:excel
/iflytek/apache-tomcat-9155/tempff9d68f1-9548-437f-a3e1-0ed93647392c_test.xlsx
也就是臨時目錄的 temp 和文件名連一塊了,結果天然而然的就是,臨時文件被上傳到了 /iflytek/apache-tomcat-9155/ 這個tomcat的安裝目錄下,致使了最開始的問題。
問題到這是解決了,但在查資料的過程當中,知道了不少新的知識。
在 tomcat 安裝目錄下的 bin/catalina.sh 這個命令裏指定了 tomcat 的臨時目錄,而在程序中經過
System.getProperty("java.io.tmpdir");
取系統的臨時目錄的時候,取的就是 tomcat 的臨時目錄,也就是 tomcat 安裝目錄下的 temp 文件夾。指定 java.io.tmpdir 對應目錄的地方也是在 bin/catalina.sh 命令裏。
首先,tomcat 啓動的時候,雖然用的啓動命令是 bin/startup.sh ,但這只是一個入口,啓動的過程都是在 bin/catalina.sh 這個命令裏,這個 catalina.sh 纔是主要的命令,你甚至能夠經過catalina.sh 這個命令啓動 tomcat 。
那麼,迴歸主題,tomcat 是如何指定它的臨時目錄的呢?
用文本編輯器打開 bin/catalina.sh 命令文件,上面是一大段註釋,從註釋中能夠看到:
CATALINA_TMPDIR 這個對應的是tomcat的臨時目錄,而 JVM 的 java.io.tmpdir 使用的就是 CATALINA_TMPDIR 對應的目錄。
接着往下翻能夠看到:
CATALINA_TMPDIR 對應的是 "$CATALINA_BASE" 下的 temp 文件夾,而 "$CATALINA_BASE" 就是 tomcat 的安裝目錄,
也就是說在這裏,指定了 tomcat 的臨時目錄是tomcat安裝目錄下的 temp 文件夾
而 tomcat 又是如何指定 CATALINA_TMPDIR 做爲 java.io.tmpdir 對應的目錄的呢?
接着往下看,能夠看到:
在執行的時候,經過 java -D 命令,指定了 JVM 的 java.io.tmpdir 系統屬性的值爲 CATALINA_TMPDIR 對應的值
能夠看到,tomcat 在啓動的時候就已經指定了 java.io.tmpdir 對應的屬性值,而且指定的是它的臨時目錄,這樣在程序中經過 java.io.tmpdir 獲取臨時目錄的時候,取到的都是tomcat的臨時目錄地址
總結一下:
一、tomcat 的臨時目錄地址是在 bin/catalina.sh 命令裏指定的,指定的默認值是 安裝目錄下的 temp 文件夾,固然也能夠根據須要修改爲本身想要設置的目錄地址
二、以 tomcat 爲容器的項目裏,經過 System.getProperty("java.io.tmpdir") 取JVM的臨時目錄地址,取到的都是tomcat的臨時目錄,這是在tomcat啓動時就指定的
三、拼接文件地址的時候,必定要注意目錄之間的分隔符 / ,沒有分隔符 / ,目錄名就成了文件名的一部分