檔案緩衝
本主題涵蓋檔緩衝應用程式控制的各種考慮,也稱為未緩衝的檔案輸入/輸出 (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開啟的檔案時,應用程式必須符合特定需求。 適用下列特定專案:
- 如果指定,則檔案存取大小,包括 重迭 結構中的選擇性檔案位移,必須為磁片區磁區大小的整數倍數位節。 例如,如果磁區大小為 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 或以 Itanium 為基礎的系統,頁面大小為 4,096 個位元組或 8,192 個位元組。 如需詳細資訊,請參閱 GetSystemInfo 函 式。
- 磁區大小通常為 512 到 4,096 個位元組,適用于直接存取存放裝置, (硬碟) ,CD-ROM 則為 2,048 個位元組。
- 頁面和磁區大小都是 2 的威力。
因此,在大部分情況下,頁面對齊記憶體也會與磁區對齊,因為磁區大小大於頁面大小很少的情況。
另一個取得手動對齊記憶體緩衝區的方法,是使用 C Run-Time 程式庫中 的 _aligned_malloc 函式。 如需如何手動控制緩衝區對齊的範例,請參閱 WriteFile的一節中的 C++ 語言程式碼範例。