本主題涵蓋檔案緩衝應用程控的各種考慮,也稱為未緩衝處理檔案輸入/輸出 (I/O)。 檔案緩衝通常由系統在幕後處理,並被視為 Windows 作業系統內檔案快取的一部分,除非另有指定。 雖然這些詞彙 快取 和 緩衝 有時會交替使用,但在本主題中,「緩衝」一詞是專門用來說明如何與未被系統快取(緩衝)的數據進行互動的,因為這些數據基本上無法由使用者模式應用程式直接控制。
概觀
使用 CreateFile 函式開啟或建立檔案時,可以指定 FILE_FLAG_NO_BUFFERING 旗標,以停用讀取或寫入檔案的數據系統快取。 雖然這可完整且直接控制數據 I/O 緩衝,但在檔案和類似裝置的情況下,必須考慮數據對齊需求。
備註
這項對齊資訊適用於裝置上的 I/O,例如支援搜尋的檔案,以及檔案位置指標的概念(或 位移)。 對於未搜尋的裝置,例如命名管道或通訊裝置,關閉緩衝可能不需要任何特定的對齊方式。 在該案例中,任何可能因對齊而獲得的限制或效率都取決於基礎技術。
在簡單的範例中,應用程式會使用 FILE_FLAG_NO_BUFFERING 旗標開啟檔案以進行寫入存取,然後使用應用程式內定義的數據緩衝區來執行 WriteFile 函式的呼叫。 在此情況下,此本機緩衝區實際上是唯一存在此作業的檔案緩衝區。 由於實體磁碟配置、文件系統記憶體配置和系統層級檔案指標位置追蹤,除非本機定義的數據緩衝區符合特定對齊準則,否則此寫入作業將會失敗,如下一節所述。
備註
快取的討論不會考慮實體磁碟本身的任何硬體快取,因為在任何情況下,這些硬體快取不一定在系統的直接控制之下。 這不會影響本主題中指定的需求。
如需有關 FILE_FLAG_NO_BUFFERING 如何與其他快取相關旗標互動的詳細資訊,請參閱 CreateFile。
對齊和檔案存取需求
如先前所述,應用程式在使用 以 FILE_FLAG_NO_BUFFERING開啟的檔案時,必須符合特定需求。 以下規範適用:
- 檔案存取大小,包括 OVERLAPPED 結構中的選擇性檔案位移,如果有指定的話,必須是磁碟區扇區大小的整數倍位元組。 例如,如果扇區大小為512個字節,則應用程式可以要求讀取和寫入512、1,024、1,536或2,048個字節,但不是335、981或7,171個字節。
- 讀取和寫入作業的檔案存取緩衝區位址應該是實體扇區對齊,這表示在記憶體中,這些位址須對應為磁碟區實體扇區大小的整數倍數。 視磁碟而定,可能不會強制執行此需求。
應用程式開發人員應該記下將新類型的存儲設備引入市場,實體媒體扇區大小為 4,096 個字節。 這些裝置的產業名稱為「進階格式」。 由於直接引入 4,096 位元組作為媒體尋址單位可能存在的相容性問題,一個暫時的相容性解決方案是引入可模擬一般 512 位元組扇區存儲裝置的設備,但藉由標準 ATA 和 SCSI 命令提供真實的扇區大小資訊。
由於此模擬,開發人員實際上需要理解兩種扇區大小:
- 邏輯扇區:用來為媒體進行邏輯區塊尋址的單位。 我們也可以將其視為記憶體可以接受的最小寫入單位。 這是「模擬」。
- 實體扇區:在單一作業中完成對裝置的讀取和寫入作業單位。 這是原子寫入的單位,無緩衝 I/O 需要與之對齊,以確保最佳效能和可靠性。
大部分最新的 Windows API,例如 IOCTL_DISK_GET_DRIVE_GEOMETRY 和 GetDiskFreeSpace,都會傳回邏輯扇區大小,但實體扇區大小可透過IOCTL_STORAGE_QUERY_PROPERTY控制程式代碼擷取,其中包含STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR 結構中BytesPerPhysicalSector 成員中的相關信息。 如需範例,請參閱 STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR的範例程序代碼。 Microsoft強烈建議開發人員依照 IOCTL_STORAGE_QUERY_PROPERTY 控制程式代碼所報告的實體扇區大小,讓未受緩衝區的 I/O 符合實體扇區大小,以協助確保其應用程式已準備好進行此扇區大小轉換。
Windows Server 2003 和 Windows XP:STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR結構不可用。 它是由 Windows Vista 和 Windows Server 2008 所引進。
因為讀取和寫入作業的緩衝區位址必須對齊扇區對齊,因此應用程式必須直接控制這些緩衝區的配置方式。 扇區對齊緩衝區的其中一種方式是使用 VirtualAlloc 函式來配置緩衝區。 請考慮下列事項:
- VirtualAlloc 會配置記憶體,這些記憶體在系統頁面大小的整數倍位址上對齊。 在 x64 和 x86 系統中,頁面大小是 4,096 字節,而在基於 Itanium 的系統中,頁面大小是 8,192 字節。 如需詳細資訊,請參閱 GetSystemInfo 函式。
- 扇區大小通常為 512 到 4,096 字節,適用於直接存取儲存設備(硬碟),而 CD-ROM 的大小為 2,048 字節。
- 頁面和扇區大小都是 2 的次方。
因此,在大部分情況下,頁面對齊的記憶體也會以扇區對齊,因為扇區大小大於頁面大小的情況很少見。
另一個取得手動對齊記憶體緩衝區的方法,是從 C Run-Time 連結庫使用 _aligned_malloc 函式。 如需如何手動控制緩衝區對齊的範例,請參閱 WriteFile 的 一節中的C++語言程式代碼範例。