2012-08-05 44 views
15

這個問題我認爲對於S/O來說足夠的技術了,而且可能也是面向編程的Android。我對如何在Android(或適當的Java或Linux)中處理文件很感興趣,因爲我用我的新智能手機做了一些事情,我很想知道它是如何發生的。爲什麼我可以在寫入Linux時成功移動文件?

我正在通過藍牙將筆記本電腦中的文件傳輸到我的Android手機。我在文件瀏覽器中看到了新文件,假設它已完全傳輸,並將其從/sdcard/bluetooth移至/sdcard/torrents。我這樣做後,我注意到它實際上仍在轉移。令我驚訝的是,它成功完成,通過手機中的通知圖標進行確認,並通過雙方的手動MD5檢查。在大多數系統中,文件移動會導致崩潰。

成功轉移的原因是什麼?我知道,一般來說,文件路徑與文件系統上的文件位置(在本例中是SD卡)是分開的。我想藍牙應用程序已經打開了文件的句柄,當我做文件移動時,一個'打開的文件'表被更新爲一個新的路徑。這個功能在任何Linux系統中通常都是如此嗎?我可以在正在編寫的文件上執行mv,並希望副本(在其新位置)是正確的嗎?

+0

兩個不同的文件系統之間爲什麼會移動文件導致崩潰開始用?這些文件本身就是二進制數據的一部分;文件系統僅表示如何存儲,表示和刪除這些數據。 – Makoto 2012-08-05 18:08:27

+1

移動一個文件本身並不會導致崩潰,但在文件上使用'mv'時,它仍然被寫入_可能會(因爲通常寫入文件的系統應該能夠假設該文件保持在從寫入開始到寫入結束的相同位置)。我想了解後一種情況是否適用於所有Linux(或Java或Android)系統。任何人都可以解釋爲什麼這個成功的額外偵察員/布朗尼點! – halfer 2012-08-05 18:11:47

回答

31

當您移動文件同一個文件系統裏面,文件本身(的inode)不動的。唯一改變的是該文件系統中的目錄條目。 (系統調用由mv在這種情況下調用爲rename(2) - 檢查該網頁以獲取更多信息和限制。)

當一個進程打開一個文件,文件名被傳遞到OS,表示該文件的意思,但你得到的文件描述符根本沒有鏈接到該名稱(你不能從中獲取文件名)–它與inode鏈接。
由於inode在重命名文件(在同一文件系統內)時保持不變,所以打開它的進程可以愉快地繼續讀取和寫入文件–沒有任何更改,它們的文件描述符仍然有效並指向右側數據。

如果你刪除一個文件,它也是一樣的。即使文件不再可通過任何目錄條目訪問,進程仍可繼續讀寫。 (這可能會導致令人困惑的情況,其中df報告您的磁盤已滿,但du表示您使用的空間少得多,df報告的空間較少。分配給仍然打開的已刪除文件的塊只有在這些進程關閉時纔會釋放文件描述符)。

如果mv跨文件系統移動文件,則行爲是不同的,因爲inode是特定於每個文件系統的。在這種情況下,mv實際上將複製數據,在目標文件系統上創建新的inode(和目錄條目)。當副本結束時,舊文件被取消鏈接,並且如果上面沒有打開的文件句柄,則刪除舊文件
在你的情況下,如果你跨越了文件系統的邊界,你會在目的地中有一個部分文件。並且您的上傳過程愉快地寫入到您無法輕鬆訪問的已刪除文件中,可能會填滿該文件系統,直到上載完成,此時inode將被刪除。

Unix & Linux一些職位,你會發現有趣:

+0

很好的答案,謝謝你。是的,我在一個文件系統中移動文件。我已經開發了類似Unix的系統多年,但之前沒有遇到過這種能力;我曾預料它會打亂作家過程。非常聰明的東西! – halfer 2012-08-05 20:12:21

相關問題