尋找最快的大檔案拷貝方法

2021-09-07 23:05:18 字數 2880 閱讀 7931

眾所周知微軟的作業系統自帶的拷貝是很「弱智」的,速度不高,無斷點續傳,而且拷貝會拖累其他的應用程式,占用大量的檔案快取。所以很多高階的拷貝工具孕育而生,用過最好的是fastcopy。fastcopy的拷貝速度基本上可以達到磁碟的極限,還因為他開源,所以可以看到其實現。但是很可惜他的工程是vc6的,而且源**注釋都是日文的,不僅如此,其源**風格很讓人迷惑。證實了我的那句話:開源軟體的最高境界就是,我開源了,你看不懂;等你看懂了,已經過時了。

要達到最快的拷貝速度和減少對記憶體的占用,需要對拷貝的過程有乙個了解。拷貝無非就是將檔案的資料讀出來,然後再寫進去的乙個過程。xp作業系統自帶的拷貝工具會首先開啟檔案控制代碼,然後將一塊資料讀取到快取中,然後再寫入到磁碟中。開啟「windows任務管理器」,程序,檢視,選擇列,開啟i/o讀取位元組,i/o寫入位元組。拷貝乙個檔案,注意explorer.exe程序即可看到整個讀寫過程。基本上可以看到xp對於檔案拷貝幾乎是屬於同時進行的,換句話說其開的快取比較小,但其效率可能並不見得很高。在我的200g seagate 7200.8硬碟上,複製速度在15m/s左右。而這個硬碟的平均讀取速度在40m/s,平均寫入速度也在35m/s以上。

在vista下面檔案拷貝做了一些優化,雖然一些bug導致複製小檔案會感覺很慢,但是複製大檔案的思路已經不同於xp了。還是開啟任務管理器,進行同樣的操作。會發現vista的會讀取將近100m後,再將檔案寫入磁碟。explorer.exe程序也會在拷貝的瞬間記憶體占用飆公升到100m以上,我的電腦商測試是120m左右,而複製完成以後記憶體占用將恢復正常。vista的狀態顯示複製速度在18m/s左右。還是沒有達到硬碟的極限速度。

觀察vista和xp的拷貝過程可以得出乙個結論,vista試圖對磁碟的拷貝做優化了,但是其無論xp的分小塊的複製,還是vista的大快取大塊複製,都不能達到磁碟的最快速度。

在兩個作業系統複製的過程中,你會發現乙個有趣的現象。xp的「任務管理器」的「效能」頁面種的「物理記憶體」種的「系統快取」的值會不斷的增大,大到乙個值以後就不會在增長。系統快取主要用於快取使用過的一些程式的記憶體、快取開啟並讀寫過的檔案,已達到更快的讀寫速度。win32 api的createfile函式預設是使用系統快取的讀寫,所以簡單的用createfile開啟的檔案是要先到系統快取的。explorer也是這樣,所以當你開啟了比較多的後台程式,複製完乙個大檔案以後,再開啟這些後台程式就變得十分緩慢,硬碟不停的讀取。這是因為檔案快取占用了太多的記憶體空間的緣故,將一些程式快取占用了,所以後台程式會變得十分緩慢。vista下面這種情況要好一些。雖然這樣的設計可以加速很多檔案操作的應用,但是對於檔案拷貝這樣的一次性操作,使用系統快取固然就是浪費資源了。

我還發現當使用fastcopy的拷貝大檔案的時候會出現另乙個現象,就是「系統快取」會驟降,磁碟讀寫速度基本達到極限。在xp下面能夠改善後台程式的效能,因為此時fastcopy使用的是不使用作業系統快取的讀寫操作,軟體自生開啟了乙個32m的快取(可自定義)。vista下面的行為有些古怪,「系統快取」也會減少,但是當複製完以後,硬碟會不斷的讀取,直到達到複製之前的大小,xp無此現象。

那麼怎麼樣才能達到極限速度呢?是需要快取還是不需要快取呢?要快取需要多大的快取才好呢?為此我做了乙個小實驗。

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using

system.io;

using

microsoft.win32.safehandles;

using

system.runtime.interopservices;

namespace

csharp

,  progress:

",speed ,progress );

}br.close();

bw.close();

sw.close();

console.writeline(

"end");

console.readline();}}

} 整個程式的思路比較簡單,開啟檔案,讀取資料到自定義的快取,然後寫入資料,關閉檔案。.net預設的filestream預設是快取的讀寫,而且沒有引數指定非快取的讀寫。但好在filestream的乙個建構函式能夠很方便的傳遞乙個控制代碼並為之所用。查閱msdn的safefilehandle時發現了createfile的用法,只需要傳遞乙個

file_flag_no_buffering給createfile,就可以實現不使用系統快取的讀寫。但使用非快取的讀寫有一些操作上的限制,詳細的可以見msdn的相關文件。

執行以上程式,對乙個segate 80g的硬碟的d盤(硬碟自身快取8m,其拷貝極限速度在26m/s左右)的乙個大檔案進行複製操作,得到的結果如下:

快取大小

不使用系統快取

拷貝速度(mb/s)

使用系統快取

拷貝速度(mb/s)

1m11.99

n/a2m

15.19

n/a4m

20.42

n/a8m

23.87

n/a16m

25.09

n/a32m

25.93

11.31

64mn/a

15.89

128m

n/a17.02

由於將在程式中將buffersize設定為64m會導致出現異常,所以64m沒有資料。對於使用快取的拷貝的速度小於32m快取的讀取速度很慢,沒有進行更多的測試。

結果很明顯,在同樣的自定義快取大小的同時,不使用系統快取的拷貝速度明顯要高於使用系統快取的拷貝速度。當不使用系統快取的拷貝時,當快取大小等於磁碟物理快取大小的時候拷貝速度就達到了90%的最大速度;當等於磁碟物理快取2倍時基本達到磁碟訪問極限。由於上述原因,這也就是為什麼fastcopy不使用系統快取的緣故了。

尋找最快的大檔案拷貝方法

眾所周知微軟的作業系統自帶的拷貝是很 弱智 的,速度不高,無斷點續傳,而且拷貝會拖累其他的應用程式,占用大量的檔案快取。所以很多高階的拷貝工具孕 育而生,用過最好的是fastcopy。fastcopy的拷貝速度基本上可以達到磁碟的極限,還因為他開源,所以可以看到其實現。但是很可惜他的工程是 vc6的...

Java 複製檔案最快方法

不考慮多執行緒優化,單執行緒檔案複製最快的方法是 檔案越大該方法越有優勢,一般比常用方法快30 private static void niotransfercopy file source,file target catch ioexception e finally 如果需要監測複製進度,可以用...

尋找最快的debian源sources list

apt get install apt spy mv sources.list sources.list.bak backup man apt spy 獲取詳細的使用方法 apt spy update 更新您的映象列表檔案 var lib apt spy mirrors.txt 3.測試各個源的速度...