Skip to content

Commit 6ac1163

Browse files
authored
Merge pull request #56 from rameel/virtual-file-extensions-cleanup
Clean up and simplify VirtualFileExtensions implementation
2 parents d1204c1 + 17765f7 commit 6ac1163

File tree

1 file changed

+19
-22
lines changed

1 file changed

+19
-22
lines changed

src/Ramstack.FileSystem.Abstractions/VirtualFileExtensions.cs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ namespace Ramstack.FileSystem;
88
/// </summary>
99
public static class VirtualFileExtensions
1010
{
11-
private static Encoding? s_utf8NoBom;
12-
13-
/// <summary>
14-
/// Gets an instance of the <see cref="UTF8Encoding"/> without BOM.
15-
/// </summary>
16-
private static Encoding Utf8NoBom => s_utf8NoBom ??= new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
17-
1811
/// <summary>
1912
/// Asynchronously returns a <see cref="StreamReader"/> with <see cref="Encoding.UTF8"/>
2013
/// character encoding that reads from the specified text file.
@@ -26,7 +19,7 @@ public static class VirtualFileExtensions
2619
/// The result is a <see cref="StreamReader"/> that reads from the text file.
2720
/// </returns>
2821
public static ValueTask<StreamReader> OpenTextAsync(this VirtualFile file, CancellationToken cancellationToken = default) =>
29-
file.OpenTextAsync(Encoding.UTF8, cancellationToken);
22+
file.OpenTextAsync(encoding: null, cancellationToken);
3023

3124
/// <summary>
3225
/// Asynchronously returns a <see cref="StreamReader"/> with the specified character encoding
@@ -67,7 +60,7 @@ public static ValueTask WriteAsync(this VirtualFile file, Stream stream, Cancell
6760
/// containing the full text from the current file.
6861
/// </returns>
6962
public static ValueTask<string> ReadAllTextAsync(this VirtualFile file, CancellationToken cancellationToken = default) =>
70-
ReadAllTextAsync(file, Encoding.UTF8, cancellationToken);
63+
ReadAllTextAsync(file, encoding: null, cancellationToken);
7164

7265
/// <summary>
7366
/// Asynchronously reads all the text in the current file with the specified encoding.
@@ -81,9 +74,15 @@ public static ValueTask<string> ReadAllTextAsync(this VirtualFile file, Cancella
8174
/// </returns>
8275
public static async ValueTask<string> ReadAllTextAsync(this VirtualFile file, Encoding? encoding, CancellationToken cancellationToken = default)
8376
{
77+
//
78+
// Use a manual read loop since .NET 6 lacks a StreamReader.ReadToEndAsync overload that accepts a CancellationToken.
79+
// This ensures the operation remains responsive to cancellation requests.
80+
//
81+
8482
const int BufferSize = 4096;
8583

86-
var stream = await file.OpenReadAsync(cancellationToken).ConfigureAwait(false);
84+
// ReSharper disable once UseAwaitUsing
85+
using var stream = await file.OpenReadAsync(cancellationToken).ConfigureAwait(false);
8786
var reader = new StreamReader(stream, encoding ??= Encoding.UTF8);
8887
var buffer = (char[]?)null;
8988

@@ -217,20 +216,20 @@ static async ValueTask<byte[]> ReadAllBytesUnknownLengthImplAsync(Stream stream,
217216
total += count;
218217
}
219218

220-
static byte[] ResizeBuffer(byte[] bytes)
219+
static byte[] ResizeBuffer(byte[] oldArray)
221220
{
222-
var length = (uint)bytes.Length * 2;
221+
var length = (uint)oldArray.Length * 2;
223222
if (length > (uint)Array.MaxLength)
224-
length = (uint)Math.Max(Array.MaxLength, bytes.Length + 1);
223+
length = (uint)Math.Max(Array.MaxLength, oldArray.Length + 1);
225224

226-
var tmp = ArrayPool<byte>.Shared.Rent((int)length);
227-
Buffer.BlockCopy(bytes, 0, tmp, 0, bytes.Length);
225+
var newArray = ArrayPool<byte>.Shared.Rent((int)length);
226+
oldArray.AsSpan().TryCopyTo(newArray);
228227

229-
var rented = bytes;
230-
bytes = tmp;
228+
var rented = oldArray;
229+
oldArray = newArray;
231230

232231
ArrayPool<byte>.Shared.Return(rented);
233-
return bytes;
232+
return oldArray;
234233
}
235234
}
236235

@@ -302,7 +301,7 @@ public static ValueTask WriteAllTextAsync(this VirtualFile file, ReadOnlyMemory<
302301
/// </returns>
303302
public static async ValueTask WriteAllTextAsync(this VirtualFile file, ReadOnlyMemory<char> contents, Encoding? encoding, CancellationToken cancellationToken = default)
304303
{
305-
var stream = await file.OpenWriteAsync(cancellationToken).ConfigureAwait(false);
304+
await using var stream = await file.OpenWriteAsync(cancellationToken).ConfigureAwait(false);
306305
await using var writer = new StreamWriter(stream, encoding!);
307306
await writer.WriteAsync(contents, cancellationToken).ConfigureAwait(false);
308307
}
@@ -331,13 +330,11 @@ public static ValueTask WriteAllLinesAsync(this VirtualFile file, IEnumerable<st
331330
/// </returns>
332331
public static async ValueTask WriteAllLinesAsync(this VirtualFile file, IEnumerable<string> contents, Encoding? encoding, CancellationToken cancellationToken = default)
333332
{
334-
var stream = await file.OpenWriteAsync(cancellationToken).ConfigureAwait(false);
333+
await using var stream = await file.OpenWriteAsync(cancellationToken).ConfigureAwait(false);
335334
await using var writer = new StreamWriter(stream, encoding, bufferSize: -1, leaveOpen: false);
336335

337336
foreach (var line in contents)
338337
await writer.WriteLineAsync(line).ConfigureAwait(false);
339-
340-
await writer.FlushAsync().ConfigureAwait(false);
341338
}
342339

343340
/// <summary>

0 commit comments

Comments
 (0)