2011-10-29 84 views
5

我已經寫了一個android應用程序,可以將大型文件保存到SD卡。偶爾我會在寫入操作期間收到IOException,導致文件被保留在損壞狀態。基於對這個問題的答案:如何安全地將文件保存到Android中的磁盤?

Question: How to safely write to a file?

我應該使用的策略是創建一個臨時文件,然後一旦寫入完成複製此文件。我的問題是:

1)這是Android上最安全的方法嗎? (例如,你可以複製android sd卡上的文件,如果是這樣的操作原子?)

2)在資源有限(磁盤空間)的嵌入式系統中,是否有人知道安全寫入磁盤的另一種策略? (而不是創建兩個大文件)

感謝

+0

對不起,我誤解了你的問題。我刪除了我的答案。 –

回答

10

典型的方式安全地創建最合理的平臺的文件(的Linux/Android的其中之一)是創建一個臨時文件,然後重命名該文件,如問題&中提到的問題所鏈接到的。注意重命名;重命名一個文件是通常是原子操作在同一個文件系統,複製一個不是。另外,這種方法只需要足夠的空間來存放單個數據副本。

因此,您使用臨時名稱在目標目錄中創建一個文件,然後使用File.renameTo()爲其指定一個正確的名稱。通過對臨時文件使用標準命名約定,您總是可以查找並刪除它們,即使您的應用程序由於設備斷電。

如果你真的偏執,你可能需要插入了幾個電話給FileDescriptor.sync()或同等...

編輯:

順便說一句,你不提你做了什麼樣的IOException以及是否你已經查明瞭它的原因。如果是因爲空間不足,那就好了,但如果我們談論的是SD卡故障,那麼在這種情況下就沒有「安全」的東西。

編輯2:

爲了檢查的可用空間,您可以創建目標目錄中File對象,然後調用File.getFreeSpace()(即您的文件將最終的目錄)。請記住,此檢查不提供任何保證 - 例如,如果沒有足夠的空間,您仍然可能會結束。另一個進程將數據寫入介質。

+0

感謝您的明確答覆。重命名非常有意義,在另一個問題上我錯過了。 – brif

+0

重命名肯定聽起來像答案。但是我想知道你可以檢查你準備寫的文件是否有足夠的SD空白空間? – Jeff

+0

@Jeff:你可以調用['File.getFreeSpace()'](http://developer.android.com/reference/java/io/File.html#getFreeSpace%28%29)來避免更明顯的情況空間不足。 – thkala

0

我不知道我是否要複製它,但重命名臨時文件是典型的。如果在寫入過程中出現異常,請刪除臨時文件。

3

我知道現在回答已經太遲了,但會幫助任何遇到此問題的人發現它有幫助。您可能需要使用AtomicFile

以下代碼片段可能會有幫助。

private void writeFile(File file, byte[] data) { 
    file.mkdirs(); 
    try { 
     AtomicFile aFile = new AtomicFile(file); 
     FileOutputStream fos = aFile.startWrite(); 
     fos.write(data); 
     aFile.finishWrite(fos); 
    } catch (IOException ioe) { 
     Log.e(TAG, "Cannot write file " + file.getPath()); 
    } 
}