diff --git a/src/Ramstack.FileSystem.Abstractions/Utilities/StreamReaderExtensions.cs b/src/Ramstack.FileSystem.Abstractions/Utilities/StreamReaderExtensions.cs
index 2b2a2c5..445dfa2 100644
--- a/src/Ramstack.FileSystem.Abstractions/Utilities/StreamReaderExtensions.cs
+++ b/src/Ramstack.FileSystem.Abstractions/Utilities/StreamReaderExtensions.cs
@@ -7,7 +7,7 @@ namespace System.IO;
///
/// Provides extension methods for the to offer API compatibility with newer .NET versions.
///
-public static class StreamReaderExtensions
+internal static class StreamReaderExtensions
{
///
/// Reads a line of characters asynchronously from the current stream and returns the data as a string.
diff --git a/src/Ramstack.FileSystem.Abstractions/VirtualFileExtensions.cs b/src/Ramstack.FileSystem.Abstractions/VirtualFileExtensions.cs
index a4ae2f4..f82d159 100644
--- a/src/Ramstack.FileSystem.Abstractions/VirtualFileExtensions.cs
+++ b/src/Ramstack.FileSystem.Abstractions/VirtualFileExtensions.cs
@@ -133,6 +133,9 @@ public static async ValueTask ReadAllBytesAsync(this VirtualFile file, C
if (length > Array.MaxLength)
throw new IOException("The file is too large.");
+ // https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/IO/File.cs#L660
+ // Some file systems (e.g. procfs on Linux) return 0 for length even when there's content.
+ // Thus we need to assume 0 doesn't mean empty.
var task = length <= 0
? ReadAllBytesUnknownLengthImplAsync(stream, cancellationToken)
: ReadAllBytesImplAsync(stream, cancellationToken);
@@ -142,16 +145,19 @@ public static async ValueTask ReadAllBytesAsync(this VirtualFile file, C
static async ValueTask ReadAllBytesImplAsync(Stream stream, CancellationToken cancellationToken)
{
var bytes = new byte[stream.Length];
- var index = 0;
+ var total = 0;
do
{
- var count = await stream.ReadAsync(bytes.AsMemory(index), cancellationToken).ConfigureAwait(false);
+ var count = await stream
+ .ReadAsync(bytes.AsMemory(total), cancellationToken)
+ .ConfigureAwait(false);
+
if (count == 0)
Error_EndOfStream();
- index += count;
- } while (index < bytes.Length);
+ total += count;
+ } while (total < bytes.Length);
return bytes;
}
@@ -171,22 +177,22 @@ static async ValueTask ReadAllBytesUnknownLengthImplAsync(Stream stream,
.ConfigureAwait(false);
if (count == 0)
- {
- var result = bytes.AsSpan(0, total).ToArray();
- ArrayPool.Shared.Return(bytes);
- return result;
- }
+ break;
total += count;
}
+ var result = bytes.AsSpan(0, total).ToArray();
+ ArrayPool.Shared.Return(bytes);
+ return result;
+
static byte[] ResizeBuffer(byte[] oldArray)
{
- var length = (uint)oldArray.Length * 2;
- if (length > (uint)Array.MaxLength)
- length = (uint)Math.Max(Array.MaxLength, oldArray.Length + 1);
+ var length = oldArray.Length * 2;
+ if ((uint)length > (uint)Array.MaxLength)
+ length = Math.Max(Array.MaxLength, oldArray.Length + 1);
- var newArray = ArrayPool.Shared.Rent((int)length);
+ var newArray = ArrayPool.Shared.Rent(length);
oldArray.AsSpan().TryCopyTo(newArray);
ArrayPool.Shared.Return(oldArray);