Windows檔案讀寫速度

2021-06-18 04:32:10 字數 3211 閱讀 3859

這幾天在研究怎麼才能加快windows檔案讀寫速度,搜了很多文章,msdn也看了不少。稍微給大家分享一下。

限制windows檔案讀寫速度的瓶頸其實最終還是**於我們硬碟的固有特性,磁碟本身的轉速和硬碟的序列化工作機制。我們所能做的只是改善軟體實現方法去逼近硬碟的極限讀寫速度。平時我們在拷貝貼上檔案的時候,其實是用的windows本身的實現,其中有乙個很大的影響速度的地方就是它們都用了windows的檔案快取機制,當你拷貝乙個大檔案時,windows會根據你要拷貝的檔案大小快取很大一部分到系統快取,這時候你會看到系統快取瞬間飆漲,機器效能大大降低。整體拷貝速度為10m/s左右。而ide 7200轉的硬碟讀寫速度一般能達到30m/s左右,所以浪費了很大一部分硬碟讀寫速度。而當我們並行讀寫多個檔案時,速度比序列讀寫多個檔案還要慢,這就是因為硬碟序列工作機制的限制,多檔案並行操作時,時間都花在磁頭擺動上了。並且在快取讀取上,命中率也將大大降低。所以我們要避免使用windows快取機制,並盡量不要同時讀寫多段檔案,盡量讀寫連續的檔案塊。

一般來說,我們操作乙個windows i/o控制代碼用的是windows檔案讀寫系列api:createfile, readfile, writefile等,這些api不僅可以讀寫檔案控制代碼,所有的i/o裝置控制代碼都能通過這些api來操作。比如socket描述符,  串列埠描述符,管道描述符等。通過設定他們的引數,我們可以選擇以不同的方式操作io。例如createfile,原型如下:

handle createfile(

lpctstr lpfilename,

//指向檔名的指標

dword dwdesiredaccess,

//訪問模式(寫/讀)

dword dwsharemode,

//共享模式

lpsecurity_attributes lpsecurityattributes,

//指向安全屬性的指標

dword dwcreationdisposition,

//如何建立

dword dwflagsandattributes,

//檔案屬性

handle htemplatefile

//用於複製檔案控制代碼

); 對於讀寫速度,最重要的是dwflagsandattributes引數,這個引數的取值可以參看msdn,這裡稍微說一下:

attributes:

該引數可以接收下列屬性的任意組合.除非其它所有的檔案屬性忽略file_attribute_normal.

file_attribute_archive

檔案將被存檔,程式使用此屬性來標誌檔案去備份或移除

file_attribute_hidden

檔案被隱藏,它不會在一般資料夾列表中被裝載.

file_attribute_normal

檔案沒有被設定任何屬性.

file_attribute_offline

檔案的資料沒有被立即用到。指出正在離線使用該檔案。

file_attribute_readonly

這個檔案只可讀取.程式可以讀檔案,但不可以在上面寫入內容,也不可刪除.

file_attribute_system

檔案是系統的一部分,或是系統專用的.

file_attribute_temporary

flags:

可以接受下列標誌的任意組合。

file_flag_write_through

指示系統通過快速快取直接寫入磁碟,

file_flag_no_buffering

當使用file_flag_no_buffering開啟檔案進行工作時,程式必須達到下列要求:

1. 檔案的訪問開頭的位元組偏移量必須是扇區尺寸的整倍數.

2. 檔案訪問的位元組數必須是扇區尺寸的整倍數.例如,如果扇區尺寸是512位元組.程式就可以讀或者寫512,1024或者2048位元組,但不能夠是335,981或者7171位元組.

3.進行讀和寫操作的位址必須在扇區的對齊位置,在記憶體中對齊的位址是扇區.尺寸的整倍數.乙個將緩衝區與扇區尺寸對齊的途徑是使用virtualalloc函式.它分配與作業系統記憶體頁大小的整倍數對齊的記憶體位址.因為記憶體頁尺寸和扇區尺寸--2都是它們的冪.這塊內存在位址中同樣與扇區尺寸大小的整倍數對齊.程式可以通過呼叫getdiskfreespace來確定扇區的尺寸.

file_flag_random_access

指定檔案是隨機訪問,這個標誌可以使系統優化檔案的緩衝.

file_flag_sequential_scan

指定檔案將從頭到尾連續地訪問.這個標誌可以提示系統優化檔案緩衝. 如果程式在隨機訪問檔案中移動檔案指標,優化可能不會發生;然而,正確的操作仍然可以得到保 證. 指定這個標誌可以提高程式以順序訪問模式讀取大檔案的效能, 效能的提高在許多程式讀取一些大的順序檔案時是異常明顯的.但是可能會有小範圍的位元組遺漏.

file_flag_delete_on_close

file_flag_backup_semantics

windows nt:指示系統為檔案的開啟或建立執行乙個備份或恢復操作. 系統保證呼叫程序忽略檔案的安全選項,倘若它必須有乙個特權.則相關的特權則是se_backup_name和se_restore_name.你也可以使用這個標誌獲得乙個資料夾的控制代碼,乙個資料夾控制代碼能夠象乙個檔案控制代碼一樣傳給某些win32函式。

file_flag_posix_semantics

指明檔案符合posix標準.這是在ms-dos與16位windows下的標準.

file_flag_open_reparse_point

指定這個標誌制約ntfs分割槽指標.該標誌不能夠和creat_always一起使用.

file_flag_open_no_recall

指明需要檔案資料,但是將繼續從遠端儲存器中接收.它不會將資料存放在本地儲存器中.這個標誌由遠端儲存系統或等級儲存管理器系統使用.

當我單獨使用file_flag_no_buffering時,拷貝貼上乙個400m檔案大概22秒,接近20m/s的速度,但是指定file_flag_no_buffering時,檔案位置,快取大小,檔案大小都有很大的限制,即都要和扇區大小對齊(見紅字部分)。如果不這樣,讀寫將失敗。這的確增大了不少記憶體分配操作,但是速度提高卻很明顯。

以上都是在本地硬碟操作的情況下,沒有網路的限制,而當我要在伺服器上拷貝檔案時,最大的瓶頸便成了網路。在這種情況下,我的想法是,伺服器的硬碟讀取速度應該大大高於我們的機器硬碟,所以可以將檔案分多段同時讀取,以爭取網路頻寬,而在寫入時則以序列的方式寫入連續的檔案。這樣既能充分利用網路,又能避免本地硬碟的讀寫速度限制。當然,具體效果還須回公司試驗。

讀寫檔案速度測試

一.檔案一次讀入速度 linux下讀檔案這東西最後都是要通過系統呼叫sys read fd,buf,count 來實現的,所以如果要提高速度,就是最簡單地呼叫sys read的封裝,比如直接用read 或fread 下面是我在linux下的幾個測試。首先建立乙個130m資料檔案 dd if dev ...

C語言檔案學習 感受檔案順序(隨機)讀寫速度

功能 1 每次讀取檔案前清除快取 2 分別計算一次寫乙個g檔案 分多次寫乙個g檔案 一次讀取乙個g檔案 逆序讀取檔案 多次從不同起點讀取檔案的時間 如下 include include include include include define n 1024 1024 1024 define m ...

windows系統讀寫INI檔案的API

ini檔案 即initialization file 這種型別的檔案中通常存放的是乙個程式的初始化資訊。ini檔案由若干個節 section 組成,每個section由若干鍵 key 組成,每個key可以賦相應的值。讀寫ini檔案實際上就是讀寫某個的section中相應的key的值,而這只要借助幾個...