Moderne .NET-Anwendungen laden Dateien möglichst nicht vollständig in den Speicher (File.ReadAllBytes / File.ReadAllText), sondern verarbeiten sie streambasiert. Das reduziert Memory-Pressure, vermeidet unnötige Kopien und skaliert deutlich besser bei großen Dateien oder parallelen Workloads. Mit async I/O, CancellationToken und deterministischem Dispose via (await) using ist das besonders sinnvoll in Services, Containern und generell überall, wo I/O nebenläufig stattfindet.
Highlights
- streambasiert, keine Voll-Buffer-Allokation
- async I/O + CancellationToken
- Hashing direkt aus dem Stream (SHA-256)
- optionales GZip-Komprimieren als Pipeline-Beispiel
using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
public static class FileStreaming
{
public static async Task<string> ComputeSha256HexAsync(string path, CancellationToken cancellationToken = default)
{
if (path is null) throw new ArgumentNullException(nameof(path));
await using var input = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024 * 128, useAsync: true);
using var sha = SHA256.Create();
byte[] hash = await sha.ComputeHashAsync(input, cancellationToken).ConfigureAwait(false);
return Convert.ToHexString(hash);
}
public static async Task CompressToGZipAsync(string sourcePath, string targetGzPath, CompressionLevel level = CompressionLevel.Optimal, CancellationToken cancellationToken = default)
{
if (sourcePath is null) throw new ArgumentNullException(nameof(sourcePath));
if (targetGzPath is null) throw new ArgumentNullException(nameof(targetGzPath));
await using var input = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024 * 128, useAsync: true);
await using var output = new FileStream(targetGzPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1024 * 128, useAsync: true);
await using var gzip = new GZipStream(output, level, leaveOpen: false);
await input.CopyToAsync(gzip, 1024 * 128, cancellationToken).ConfigureAwait(false);
}
}
Kommentare zum Snippet