Sdílet prostřednictvím


FileStream už nesynchronizuje posun souboru s operačním systémem

Pokud chcete zvýšit výkon, FileStream už nesynchronizuje posun souboru s operačním systémem.

Změna popisu

V předchozích verzích FileStream .NET synchronizuje posun souboru s operačním systémem Windows při čtení nebo zápisu do souboru. Synchronizuje posun voláním SetFilePointer, což je nákladné systémové volání. Počínaje rozhraním .NET 6 FileStream se už nesynchronizuje posun souboru a místo toho zůstane posun v paměti. FileStream.Position vždy vrátí aktuální posun, ale pokud získáte popisovač souboru z FileStream.SafeFileHandle operačního systému a dotazujete se na operační systém pro posun aktuálního souboru pomocí systémového volání, hodnota posunu bude 0.

Následující kód ukazuje, jak se posun souboru liší mezi předchozími verzemi .NET a .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
    }
}

Zavedená verze

.NET 6

Důvod změny

Tato změna byla zavedena za účelem zlepšení výkonu asynchronních čtení a zápisů a řešení následujících problémů:

Díky této změně ReadAsync jsou operace až dvakrát rychlejší a WriteAsync operace jsou až pětkrát rychlejší.

  • Upravte veškerý kód, který spoléhal na synchronizaci posunu.

  • Pokud chcete povolit chování .NET 5 v .NET 6, zadejte AppContext přepínač nebo proměnnou prostředí. Nastavením přepínače na truemožnost se odhlásíte ze všech vylepšení výkonu provedených FileStream v .NET 6.

    {
        "configProperties": {
            "System.IO.UseNet5CompatFileStream": true
        }
    }
    
    set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
    

    Poznámka:

    Tento přepínač je k dispozici pouze v .NET 6. Byl odebrán v .NET 7.

Ovlivněná rozhraní API

Nezaokrouhlovat.

Viz také