Neu in .NET 6 [14]: Direkte Dateizugriffe ohne Stream-Objekte
Die Serie zu den Neuerungen in .NET 6 behandelt im vierzehnten Teil die Klasse System.IO.RandomAccess
- Dr. Holger Schwichtenberg
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().
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.