2011-11-30 77 views
9

在Guava 10+中,Google已棄用Files.deleteDirectoryContents()。 JavaDoc說爲什麼在Guava中不推薦使用Files.deleteDirectoryContents()?

已棄用。這種方法遇到糟糕的符號鏈接檢測和競爭條件。此功能僅適用於支持操作系統命令(例如rm -rf或del/s)的 。 此方法定於番石榴番石榴除去釋放 11.0

我對爲什麼會出現競爭條件困惑。我認爲這種方法實際上很有用,並且發現向操作系統提出一個糟糕的解決方案。作者可以分享爲什麼做出這個決定嗎?

+0

更清晰,我覺得有競爭狀態的問題不是主要的錯誤。許多庫,像'ArrayList'不是線程安全的或者有競爭條件。即使'File.remove'也有同樣的問題。但他們都記錄在案。所以我希望聽到一個答案,除了文件已經說了他們爲什麼選擇使其不推薦使用。 –

+1

這種競爭條件和典型的非線程安全類之間的區別在於它沒有「修復」。相比之下,您可以通過同步鎖對象來解決非線程安全類的Java線程安全問題。一種根本無法做到人們所期望的方法是一種不好的方法。 –

+0

這是一個很好的觀點。謝謝。 –

回答

5

我很困惑爲什麼有一個競爭條件。

例如,假設一個線程調用Files.deleteDirectoryContents()和第二螺紋(或外部過程)同​​時在目錄中創建新的文件。

當您從通話中返回時,您可以依賴目錄爲空嗎?不!

無論如何,如果你發現這個方法的功能是有用的......儘管它的缺陷......你可以自由地獲取代碼的副本,調整它,並將其嵌入到你的應用程序中。 (只需檢查番石榴的源代碼許可證,並確保符合它。)

作者可以分享爲什麼做出此決定?

我認爲他們已經有;請參閱棄用通知。如果您需要更多,請嘗試搜索問題跟蹤器和Guava討論組。你甚至可以嘗試在討論小組中禮貌地問,但如果你的議程要改變他們的想法,我懷疑你會成功。

+4

炮擊到操作系統也是如此,不是嗎? – anders

+0

+1對OS不一樣。我認爲如果一個庫不是線程安全的,那麼它應該被記錄下來,並由開發人員確定它們是否正確使用它。 –

+0

@Stephen C,我不想改變任何身體的想法。我肯定有一個很好的理由,爲什麼這是不贊成的。我只是覺得除了競賽狀況之外,還有一個問題可能會被迫做。但有很多庫存有競爭條件。我想也許會有更好的理由。 –

5

競爭條件可能比「目錄可能不爲空」更糟糕,這部分是由於糟糕的符號鏈接檢測。考慮下面的代碼片段:

// Symbolic links will have different canonical and absolute paths 
if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) { 
    return; 
} 
... delete its contents ... 

如果directory是在檢查過程中一個普通的目錄,但一個符號鏈接/之後,deleteDirectoryContents將愉快地試圖消滅整個文件系統。

也許有一個解決方法,但我們還沒有找到它。爲潛在的安全漏洞做臨時修復是可怕的。

1

有關斷鏈符號鏈接檢測的更多示例,請參閱these bugs filed by users

總之,除非您提供該目錄的規範路徑,否則不可能擦除目錄。如果/tmp/some/other/directory的鏈接,則deleteDirectoryContents無法清除/tmp/mytempdirectory。也許這裏也有可能的解決方法,但我們舉起手來。

1

你是認真的嗎?您正試圖解決多線程操作:

例如,假設一個線程調用文件。deleteDirectoryContents()和第二個線程(或外部進程)同時在目錄中創建一個新文件。 當您從通話中返回時,您可以依賴目錄爲空嗎?不!

又是怎麼回事另一個進程上的目錄操作???它不能解決,你不應該處理交易,因爲這是不可能的。並且有人認爲有人將symlink連接到root,所以我刪除整個文件系統 - 不應該獲得文件系統處理該權限的權限?如果你正在運行root這樣的操作,你應該知道你在做什麼。怎麼樣在文件系統中禁用刪除文件,這是危險的!如果番石榴的作者解決這些白癡問題,我將使用不同的圖書館。

相關問題