我正在尋找覆蓋已存在的文件的內容。顯然,我可以創建一個覆蓋舊文件的新文件,按照this answer。但是,我正在編寫一個程序,這個程序可能會進行很多次,我想盡可能地減少不必要的開銷。有沒有更好的方法來覆蓋文件內容?
所以我的問題是:是否有更好的方法來簡單地重寫文件本身的內容,而不是寫一個替換舊文件的「新」文件?或者是簡單地覆蓋整個文件內容大致相當於創建新文件並寫入它的開銷的開銷? (爲了記錄,這些文件只有1 KB大。)
我正在尋找覆蓋已存在的文件的內容。顯然,我可以創建一個覆蓋舊文件的新文件,按照this answer。但是,我正在編寫一個程序,這個程序可能會進行很多次,我想盡可能地減少不必要的開銷。有沒有更好的方法來覆蓋文件內容?
所以我的問題是:是否有更好的方法來簡單地重寫文件本身的內容,而不是寫一個替換舊文件的「新」文件?或者是簡單地覆蓋整個文件內容大致相當於創建新文件並寫入它的開銷的開銷? (爲了記錄,這些文件只有1 KB大。)
簡短的回答:寫兩個和配置文件。
帶有較長的答案相當揮手:
覆蓋一個文件會涉及到以下系統調用:
open
write
close
創建一個新的文件,刪除舊文件,然後重命名新的文件將包括以下系統調用:
open
write
close
unlink
rename
系統調用通常程序的最慢的部分;一般來說,減少系統調用是加速程序的好方法。覆蓋一個文件將重新使用操作系統的內部目錄條目數據;這可能也會導致一些速度的提升。 (它們可能難以用虛擬機開銷語言來衡量......)
您的文件足夠小,以至於每個write()
都應該以原子方式處理,假設您在一次寫入中更新整個1K。 (因爲你關心性能,這似乎是一個安全的假設。)這意味着其他進程不應該看到部分寫入,除非發生災難性電源故障和有損掛載選項。 (不常見)。即使面對多次寫入,文件重命名方法也會提供一致的文件。
但是,1K文件是一個相當低效的存儲機制;許多文件系統將沿着4k塊寫入文件。如果這些數據塊僅存在於您的應用程序中,則可以將它們寫入容器,這些容器可以是某種類型的,每次可以多個。 (因爲巨大的流IO請求比數千個更小的IO請求要快得多,因此Quake派生系統會從zip文件中讀取它們的地圖,紋理等等。)當然,如果您的應用程序正在編寫這些文件可供其他應用程序使用,但是如果這些文件很少共享,可能仍值得研究。
只是用它作爲鏈接答案的一個例子。讓操作系統/文件系統擔心取消鏈接/鏈接索引節點,磁盤上的位置等等。現在很少有很好的理由擔心絕大多數軟件開發。
一般來說,CPU /磁盤I/O不會造成太多開銷。如果您關心磁盤I/O,請在SATA3上使用內存文件系統(假設您不需要在發生崩潰時保留文件)或非常快速的SSD。
你可以在這裏使用RandomAccessFile
是一個簡短的樣本:
// create a new RandomAccessFile with filename test
RandomAccessFile raf = new RandomAccessFile("c:/test.txt", "rw");
// write something in the file
raf.writeUTF("Hello World");
// set the file pointer at 0 position
raf.seek(0);
// print the string
System.out.println("" + raf.readUTF());
// print current length
System.out.println("" + raf.length());
// set the file length to 30
raf.setLength(30);
// print the new length
System.out.println("" + raf.length());
但是,只有當您以隨機訪問的方式訪問數據時,並且只有在您使用完全相同長度的數據替換精確長度的數據時。 –
@ialiashkevich真棒,這正是我正在尋找的選擇。這些文件總是大致相同的長度(它們基本上只是在特定模式下的數字),所以這似乎可以工作。但是現在,原來的問題是:什麼開銷較少 - 你的方法,或者我在原文中鏈接到的答案的方法? – MattS
如果只重寫文件的一部分,則RandomAccessFile的開銷較小。重寫整個文件將與原始文章的答案相同。
由於您的程序調用了另一個程序,它將某種格式的文件作爲輸入,因此不應該擔心文件寫入開銷,調用另一個程序會佔用系統的大部分資源。
我會建議在多線程中同時寫入文件和調用程序,在這種情況下,您可以獲得最大的硬件性能。 –
ialiashkevich
你瞭解文件如何存儲在磁盤上,以及如何限制他們如何處理,是否正確? –
我不確定我明白你在問什麼。我有一定的理解,但我不會說我是磁盤數據存儲方面的專家。我是第二年和第三年的計算機科學專業的學生(這不是家庭作業),所以我們已經介紹了一些文件存儲,但是在我的課堂上並沒有多少東西。 – MattS
如何使用像[Redis](http://redis.io/)這樣的數據庫或鍵值存儲而不是文件? –