public static void WriteAllBytes(string path, byte[] bytes) { ArgumentException.ThrowIfNullOrEmpty(path); ArgumentNullException.ThrowIfNull(bytes); using SafeFileHandle sfh = OpenHandle(path, FileMode.Create, FileAccess.Write, FileShare.Read); RandomAccess.WriteAtOffset(sfh, bytes, 0); }
private static void WriteToFile(string path, FileMode mode, string?contents, Encoding encoding) { ReadOnlySpan <byte> preamble = encoding.GetPreamble(); int preambleSize = preamble.Length; using SafeFileHandle fileHandle = OpenHandle(path, mode, FileAccess.Write, FileShare.Read, FileOptions.None, GetPreallocationSize(mode, contents, encoding, preambleSize)); long fileOffset = mode == FileMode.Append && fileHandle.CanSeek ? RandomAccess.GetLength(fileHandle) : 0; if (string.IsNullOrEmpty(contents)) { if (preambleSize > 0 && // even if the content is empty, we want to store the preamble fileOffset == 0) // if we're appending to a file that already has data, don't write the preamble. { RandomAccess.WriteAtOffset(fileHandle, preamble, fileOffset); } return; } int bytesNeeded = preambleSize + encoding.GetMaxByteCount(Math.Min(contents.Length, ChunkSize)); byte[]? rentedBytes = null; Span <byte> bytes = bytesNeeded <= 1024 ? stackalloc byte[1024] : (rentedBytes = ArrayPool <byte> .Shared.Rent(bytesNeeded)); try { if (fileOffset == 0) { preamble.CopyTo(bytes); } else { preambleSize = 0; // don't append preamble to a non-empty file } Encoder encoder = encoding.GetEncoder(); ReadOnlySpan <char> remaining = contents; while (!remaining.IsEmpty) { ReadOnlySpan <char> toEncode = remaining.Slice(0, Math.Min(remaining.Length, ChunkSize)); remaining = remaining.Slice(toEncode.Length); int encoded = encoder.GetBytes(toEncode, bytes.Slice(preambleSize), flush: remaining.IsEmpty); Span <byte> toStore = bytes.Slice(0, preambleSize + encoded); RandomAccess.WriteAtOffset(fileHandle, toStore, fileOffset); fileOffset += toStore.Length; preambleSize = 0; } } finally { if (rentedBytes is not null) { ArrayPool <byte> .Shared.Return(rentedBytes); } } }