前言:最近使用springboot處理文件上傳。但是遇到了一些莫名其妙的問題。
需求是:前端上傳一個excel,後端需要接收並解析裏面每行數據,並最後生成一個結果excel提供下載。
由於考慮到如果用戶上傳的excel數據量大的時候,解析過程可能要持續很久,所以採用了異步開線程@Async的方式去處理。具體實現是:controller被調用後會進行文件的合法性判斷,判斷通過後就異步調用有@Async的方法,異步方法處理:1,文件保存至服務端 2,文件解析並生成新的文件。
但是卻碰到這樣的報錯:
java.io.FileNotFoundException: /tmp/var/folders/w6/tomcat.5030557797053639217.9981/work/Tomcat/localhost/ROOT/upload_d5323221_777b_40a1_8850_258388c80621_00000001.tmp (No such file or directory)
我開始認爲是我寫的路徑有問題,但排查後沒問題。
然後我又認爲是保存文件到服務端的方法有問題,但是同步調用的時候整個流程是ok的。
上面提示很明顯,就是找不到文件或目錄,但這個文件或目錄不是我定義的啊?且找不到的文件後綴名是tmp。就猜想是不是生成的臨時文件,果然,查閱相關資料後,確實如此。
錯誤原因:
由於springboot上傳文件之後形成MultipartFile的實例,會在臨時文件夾生成臨時文件。MultipartFile的實例交給異步線程處理後,該臨時文件會被springboot清理掉,就會引起上面的異常。
解決辦法:
文件保存至服務端不要放在異步方法內做。
參考資料:
FileNotFoundException while uploading multi part file - Spring boot