FileStream artık dosya uzaklığını işletim sistemiyle eşitlemez
Performansı geliştirmek için artık FileStream dosya uzaklığını işletim sistemiyle eşitlemez.
Açıklama değiştirildi
Önceki .NET sürümlerinde, FileStream bir dosyayı okuduğunda veya yazdığında dosya uzaklığını Windows işletim sistemiyle (OS) eşitler. Pahalı bir sistem çağrısı olan SetFilePointer'ı çağırarak uzaklığı eşitler. .NET 6'dan başlayarak, FileStream artık dosya uzaklığını eşitlemez ve bunun yerine uzaklığı bellekte tutar. FileStream.Position her zaman geçerli uzaklığı döndürür, ancak bir sistem çağrısı kullanarak dosya tutamacını alıp FileStream.SafeFileHandle geçerli dosya uzaklığı için işletim sistemini sorgularsanız, uzaklık değeri 0 olur.
Aşağıdaki kod, dosya uzaklığının önceki .NET sürümleriyle .NET 6 arasında nasıl farklılık gösterdiğini gösterir.
[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
}
}
Sürüm kullanıma sunulmuştur
.NET 6
Değişiklik nedeni
Bu değişiklik, zaman uyumsuz okuma ve yazmaların performansını geliştirmek ve aşağıdaki sorunları çözmek için kullanıma sunulmuştur:
- Win32 FileStream her ReadAsync çağrısında bir arama oluşturur
- FileStream.Windows useAsync WriteAsync çağrıları API'leri engelliyor
Bu değişiklikle, ReadAsync işlemler iki kata kadar daha hızlıdır ve WriteAsync işlemler beş kata kadar daha hızlıdır.
Önerilen eylem
Eşitlenen uzaklığı kullanan tüm kodları değiştirin.
.NET 6'da .NET 5 davranışını etkinleştirmek için bir
AppContext
anahtar veya ortam değişkeni belirtin. anahtarını olaraktrue
ayarlayarak .NET 6'da yapılanFileStream
tüm performans geliştirmelerini geri çevirmiş olursunuz.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Not
Bu anahtar yalnızca .NET 6'da kullanılabilir. .NET 7'de kaldırıldı.
Etkilenen API’ler
Yok.
Ayrıca bkz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin