2016-07-08 46 views
2

我試圖以編程方式從包含多個Java和非Java服務器的正在運行的(!)系統中清除日誌文件。我使用Java的File.delete()操作,它通常工作正常。對於當前正在使用的日誌文件沒有被刪除,我也很完美,所以只要File.delete()返回false就將其作爲警告記錄下來。Java的File.delete()有時會留下無法訪問的文件(Windows)

但是,在當前仍由非Java應用程序(Postgres,Apache HTTPD等)編寫的日誌文件中,Java應用程序可能也會受到影響,但我還沒有注意到,並且所有使用的都是相同的但是,File.delete()會爲它們返回「true」。 但這些文件不僅在文件系統上仍然存在(Windows資源管理器和「dir」仍然顯示它們),但之後它們無法訪問......當我嘗試用文本編輯器等打開它們時,我得到「訪問被拒絕「或類似的錯誤消息,當我嘗試複製它們與資源管理器時,它也聲稱我沒有權限,當我用資源管理器檢查其」屬性「,它給了我」你沒有權限查看或編輯此對象的權限」。

只是要清楚:在我運行File.delete()操作之前,我可以在沒有任何問題的情況下訪問或刪除這些文件,刪除操作會「中斷」它們。一旦我停止了應用程序,文件就會消失,重新啓動時,應用程序會從頭開始創建它,一切都恢復正常。 問題是,在日誌文件清除操作後未重新啓動應用程序時,應用程序會記錄到涅v。

這種行爲讓我想起了Linux的一些文件刪除行爲:如果你刪除了一個仍然被應用程序打開的文件,它將從文件系統中消失,但應用程序仍然保存文件句柄高興地繼續寫入該文件,但之後你將永遠無法訪問它。唯一的區別是,這裏的文件在FS中仍然可見,但也無法訪問。

我應該提到我的Java程序和應用程序本身都是以「系統」用戶運行的。

我也試過Files.delete(),它涉嫌拋出一個IOException指示錯誤......但似乎沒有錯誤。

我試圖解決這個問題的方法是使用這裏描述的方法https://stackoverflow.com/a/1390669/5837050來檢查文件是否當前被鎖定,但這隻適用於某些文件,而不適用於所有文件。

我基本上需要一種可靠的方法(至少對於Windows來說,如果它也適用於Linux,那將非常棒)來確定某個程序是否仍在使用某個文件,因此我可以不刪除它。

任何提示讚賞。

+1

@Divyesh:你發佈的鏈接引入了一般的Java併發功能 - 不確定它們應該如何幫助,因爲我想要刪除的文件實際上甚至不是由我自己的Java應用程序編寫的,而是由各種第三方Java和非Java應用程序。 – MellowCoder

回答

0

我沒有轉載它,但它似乎是一個操作系統的預期行爲,通常不同的應用程序運行不同的用戶擁有這種類型的文件的所有權,但我明白,你想像一個主要清除Java檢查日誌文件不用於刪除它們(當然,運行時有足夠的補助金)。

因此,考慮到操作系統行爲不會改變,我建議使用「roll file appender」策略來配置日誌,然後檢查與這些策略匹配的文件。

檢查的logback回滾政策,讓你的想法: http://logback.qos.ch/manual/appenders.html#onRollingPolicies

例如,如果你的appender文件政策是「超過一天或1GB以上」,則直接刪除文件,這最後的版本日期都超過一天或大小是1Gb。有了這個規則,你一定會刪除未被使用的日誌文件。

注意..用適當的滾動策略也許你甚至不需要你的淨化方法,看看這個配置示例:

<!-- keep 30 days' worth of history capped at 3GB total size --> 
    <maxHistory>30</maxHistory> 
    <totalSizeCap>3GB</totalSizeCap> 

我希望這能幫助你一點!