Die Serie zu den Neuerungen in .NET 6 behandelt im vierzehnten Teil die Klasse System.IO.RandomAccess
.
.NET 6 bietet eine neue Klasse System.IO.RandomAccess
für den Dateisystemzugriff, die performanter ist als die bisherigen Zugriffe mit Stream-Objekten.
Das folgende Listing zeigt die neue Klasse im Einsatz beim Schreiben einer Datei mit Write()
und beim Lesen mit Read()
.
public static void FileIOWithoutStream()
{
var path = System.IO.Path.GetTempFileName();
#region ------- Dateiinhalte schreiben ohne Stream-Objekte
using (Microsoft.Win32.SafeHandles.SafeFileHandle handle
= File.OpenHandle(path, FileMode.Create,
FileAccess.Write))
{
var arr = new byte[100];
arr = Encoding.ASCII.GetBytes("1234567890abcdef" +
"1234567890abcdef1234567890abcdef" +
"1234567890abcdef1234567890abcdef" +
"1234567890abcdef1234567890abcdef" +
"1234567890abcdef1234567890abcdef");
int startpos = 00;
Span<byte> buffer = arr;
RandomAccess.Write(handle, buffer, startpos);
handle.Close();
}
#endregion
#region ------- Dateiinhalte lesen ohne Stream-Objekte
using (Microsoft.Win32.SafeHandles.SafeFileHandle handle
= File.OpenHandle(path))
{
// Dateilänge ermitteln
long length = RandomAccess.GetLength(handle);
Console.WriteLine(length);
// 100 Bytes einlesen, erste 10 Zeichen überspringen
var arr = new byte[100];
int startpos = 10;
Span<byte> buffer = arr;
var bytesRead = RandomAccess.Read(handle, buffer, startpos);
Console.WriteLine("Puffergröße: " + buffer.Length);
Console.WriteLine("Eingelesene Bytes: " + bytesRead);
Console.WriteLine("Inhalte an Position 1:"
+ (char)arr[0]); // a
Console.WriteLine("Inhalte an Position 11:"
+ (char)arr[10]); // 5
Console.WriteLine("Inhalte an Position 99:"
+ (char)arr[98]); // c
handle.Close();
}
#endregion
}
In einem Leistungsvergleich für das sequentielle Schreiben einer Datei mit 100 MB Inhalt ist RandomAccess.Write()
schneller als die Nutzung von Stream-Objekten, aber die Methode WriteAllBytes()
liegt noch vor RandomAccess.Write()
.
Geschwindigkeit beim Schreiben einer 100-MB großen Datei
Das erklärt sich leider nicht beim Blick in die Dokumentation, sondern nur, wenn man sich die Mühe macht, den Quellcode von WriteAllBytes()
in .NET 6 mit der Implementierung vorher (.NET 5) zu vergleichen. Dann sieht man, dass WriteAllBytes()
nun intern System.IO.RandomAccess
und damit auch andere Betriebssystem-APIs verwendet.
WriteAllBytes() in .NET 5 und .NET 6
()