2017-02-23 45 views
1

作爲每API,這些都是事實:RandomAccessFile.seek()如何工作?

  • seek(long bytePosition)方法簡單地說,將指針移動到 與bytePosition參數指定的位置。
  • bytePosition大於文件長度時,文件 長度不會改變,除非在(新)結束處寫入一個字節。
  • 如果數據以跳過的長度存在,則這些數據不會被觸發,而是保留 。

不過,我很好奇的情況是:當有沒有數據(0字節)的文件,我執行下面的代碼:

file.seek(100000-1); 
file.write(0); 

所有100,000字節幾乎立即填滿0。比如說,我可以在10毫秒內超過200GB。

但是,當我嘗試使用其他方法(例如BufferedOutputStream)寫入100000字節時,同一個過程需要幾乎無限長的時間。

這種時間差異的原因是什麼?有沒有更有效的方法來創建n字節的文件並填寫0

編輯: 如果數據沒有實際寫入,那麼文件如何填充數據? 樣品驗證碼:

RandomAccessFile out=new RandomAccessFile("D:/out","rw"); 
out.seek(100000-1); 
out.write(0); 
out.close(); 

這是輸出:

Output

另外,如果該文件是足夠龐大的我不能再寫入磁盤,由於缺乏空間。

+0

我的猜測是文件大小是「注意到」的,但實際的塊沒有寫入磁盤。沖洗/關閉需要多長時間? (請參閱這裏http://stackoverflow.com/a/257849/540873) –

+0

我的猜測是一樣的,但我打開文件並檢查它。當我沒有寫最後一個字節時,它是空的,結果文件大小爲0字節。當我寫完最後一個字節時,直到最後一個字節的每個字節都填充0,文件大小作爲輸入。包含close()操作的整個過程是問題中指定的時間(這就是爲什麼我很驚訝!) – SirVirgin

+0

當您閱讀該方法的源代碼時,您不明白什麼?在請求別人閱讀它之前,確實已經閱讀了信息來源,你是否爲你工作了嗎? –

回答

3

當你寫100,000字節到BufferedOutputStream,你的程序是明確的訪問文件的每個字節,寫一個零。

在本地文件上使用RandomAccessFile.seek()時,您間接使用C系統調用fseek()。如何處理取決於操作系統。

在大多數現代操作系統,sparse files支持。這意味着如果您要求一個空的100,000字節文件,實際上並未使用100,000個字節的磁盤空間。當您寫入字節100,001時,操作系統仍然不使用100,001字節的磁盤。它爲包含「真實」數據的塊分配少量空間,並分別跟蹤空閒空間。

當你閱讀稀疏文件,例如,通過fseek() ING至字節50,000,然後看書,操作系統可以說「爲字節50000 OK,我還沒有分配的磁盤空間,因爲我已經注意到,字節0〜 100,000是空的,因此我可以爲這個字節返回0。「。這對調用者來說是不可見的。

這具有節省磁盤空間和提高速度的雙重目的。你已經注意到速度的提高。

更一般地,fseek()直接進入在文件中的位置,所以它的O(1),而不是爲O(n)。如果你將一個文件與一個數組進行比較,就像做x = arr[n]而不是for(i = 0; i<=n; i++) { x = arr[i]; }

這個描述和維基百科上的描述可能足以理解爲什麼尋找字節100,000然後寫入比寫入10萬個零更快。但是,您可以閱讀Linux內核源代碼以查看稀疏文件的實現方式,您可以閱讀JDK中的RandomAccessFile源代碼以及JRE源代碼,以瞭解它們如何交互。但是,這可能比您需要的更詳細。

+0

爲什麼downvote?這是一個很好的答案。 – Gray

+0

我沒有downvote。請參閱編輯 – SirVirgin

+0

此答案處理您的編輯以及@RangaRajan。數據是由稀疏文件處理的0。 – Gray

1

您的操作系統和文件系統支持稀疏文件時,它的的情況下,尋求實現利用這一功能。

這不是真的與Java有關,它只是C庫中的fseekfwrite函數的一個特性,它很可能是您正在使用的JRE的文件實現背後的後端。

更多信息:https://en.wikipedia.org/wiki/Sparse_file

是否有創建的n個字節的文件,並以0填充它更有效的方法?

在支持它的操作系統上,您可以將truncate文件轉換爲所需的大小,而不是發出write調用。但是,這似乎在Java API中不可用。

+0

你會如此善良以詳細說明嗎?另外如何實現seek()方法?有沒有一種方法可以看到內置的庫方法是如何實現的? – SirVirgin

+0

爲什麼downvote?這是一個很好的答案。 – Gray

+0

我沒有downvote。另外,請參閱編輯。 – SirVirgin