다음을 통해 공유


FileStream이 더 이상 파일 오프셋을 OS와 동기화하지 않음

성능 향상을 위해 FileStream은 더 이상 파일 오프셋을 운영 체제와 동기화하지 않습니다.

변경 내용 설명

이전 .NET 버전에서 FileStream은 파일을 읽거나 쓸 때 파일 오프셋을 Windows OS(운영 체제)와 동기화합니다. 비용이 많이 드는 시스템 호출인 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 작업은 최대 2배 더 빨라지고 WriteAsync 작업은 최대 5배 더 빨라집니다.

  • 동기화되는 오프셋에 의존하는 코드를 수정합니다.

  • .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

없음

참고 항목