若要改善效能,FileStream 不再與作業系統同步檔案位移。
變更描述
在先前版本的 .NET 中,FileStream 會在檔案讀取或寫入檔案時,將檔案位移與 Windows 作業系統同步。 它會藉由呼叫 SetFilePointer 來同步位移,這是耗費大量資源的系統呼叫。 從 .NET 6 開始, FileStream 不再同步處理檔案位移,而只會將位移保留在記憶體中。 FileStream.Position 一律會傳回目前的位移,但如果您從 FileStream.SafeFileHandle 取得檔句柄,並使用系統呼叫查詢 OS 的目前檔案位移,則位移值會是 0。
下列程式代碼顯示檔案位移在舊版 .NET 和 .NET 6 之間有何差異。
[DllImport("kernel32.dll")]
private static extern bool SetFilePointerEx(SafeFileHandle hFile, long liDistanceToMove, out long lpNewFilePointer, uint dwMoveMethod);
byte[] bytes = new byte[10_000];
string path = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize: 4096, useAsync: true))
{
SafeFileHandle handle = fs.SafeFileHandle;
await fs.WriteAsync(bytes, 0, bytes.Length);
Console.WriteLine(fs.Position); // 10000 in all versions
if (SetFilePointerEx(handle, 0, out long currentOffset, 1 /* get current offset */))
{
Console.WriteLine(currentOffset); // 10000 in .NET 5, 0 in .NET 6
}
}
推出的版本
.NET 6
變更的原因
這項變更已導入,以改善異步讀取和寫入的效能,並解決下列問題:
有了這項變更, ReadAsync 作業的速度最多可加快兩倍,且 WriteAsync 作業速度高達五倍。
建議的動作
修改任何依賴同步位移的程序代碼。
若要在 .NET 6 中啟用 .NET 5 行為,請指定
AppContext
參數或環境變數。 將開關設定為true
,您可以退出 .NET 6 中對FileStream
進行的所有效能改進。{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
備註
此參數僅適用於 .NET 6。 它已在 .NET 7 中移除。
受影響的 API
沒有。