Share via


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:

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.

  • 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ı olarak trueayarlayarak .NET 6'da yapılan FileStream 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.