我正在開發一個RESTful Web服務,它允許用戶下載從數據庫中動態檢索的csv和json格式的數據。下載大文件 - 使用grails的應用程序
現在我正在使用StringWriter寫出CSV數據。我主要關心的是結果集可能會變得非常大,取決於用戶輸入。在這種情況下,讓他們都成爲記憶對我來說似乎不是個好主意。
我正在考慮創建一個臨時文件,但是如何確保文件在下載完成後立即被刪除。
有沒有更好的方法來做到這一點。
感謝您的幫助。
我正在開發一個RESTful Web服務,它允許用戶下載從數據庫中動態檢索的csv和json格式的數據。下載大文件 - 使用grails的應用程序
現在我正在使用StringWriter寫出CSV數據。我主要關心的是結果集可能會變得非常大,取決於用戶輸入。在這種情況下,讓他們都成爲記憶對我來說似乎不是個好主意。
我正在考慮創建一個臨時文件,但是如何確保文件在下載完成後立即被刪除。
有沒有更好的方法來做到這一點。
感謝您的幫助。
那麼,防止臨時文件長時間滯留的最簡單的解決方案應該是一個cron作業,它簡單地刪除臨時目錄中修改時間早於1小時的任何文件。
如果您希望它在Grails中完成,您可以設計一個Quartz作業來清理文件。這項工作可以如上所述完成(只需檢查修改時間戳以決定要刪除的內容),或者您可以僅在需要時使用要刪除的文件名參數運行作業。一旦下載操作被調用,您可以安排在X分鐘後清理該特定文件(以便有足夠的時間成功下載)。然後該工作將負責簡單地刪除該文件。
要創建會話過期後自動刪除的臨時文件,可以使用Session Temp Files plugin。
根據涉及的文件數量,您總是可以使用http://download.oracle.com/javase/1,5.0/docs/api/java/io/File.html#deleteOnExit()確保在VM關閉時文件被吹走。
如果內存問題,您可以簡單地寫出直接寫入輸出流的響應寫入器?這樣,你不是在內存中存儲任何東西(多)沒必要寫出來的臨時文件:
// controller action for CSV download
def download = {
response.setContentType("text/csv")
response.setHeader("Content-disposition", "attachment;filename=downloadFile.csv")
def results = // get all your results
results.each { result ->
out << result.col1 << ',' << result.col2 // etc
out << '\n'
}
}
此寫出到輸出流,因爲它是循環圓你的結果。
理論上你可以通過使用可滾動結果集來提高內存的效率 - 請參閱Querying with GORM - Criteria的「使用可滾動結果」部分 - 循環寫入響應編寫器。理論上這意味着你也沒有將所有數據庫結果加載到內存中,但實際上,如果你使用MySQL(及其Java連接器),這可能無法按預期工作。手動批量查詢也可能會發揮作用(獲取數據庫行1-10000,寫出,獲得10001-20001等)
這種事情對於JSON可能會更困難,具體取決於您使用哪個庫來呈現你的對象。
謝謝..聲音像一個很好的解決方案.. – 2011-05-25 22:53:59
有一個Grails石英插件,可以很容易地在Grails應用程序內運行作業 – 2011-05-26 08:23:34