Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 7 additions & 36 deletions src/Ramstack.FileProviders.Extensions/FileInfoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,38 +153,11 @@ public static ValueTask<string> ReadAllTextAsync(this IFileInfo file, Cancellati
/// </returns>
public static async ValueTask<string> ReadAllTextAsync(this IFileInfo file, Encoding? encoding, CancellationToken cancellationToken = default)
{
const int BufferSize = 4096;

var stream = file.OpenRead();
var reader = new StreamReader(stream, encoding ??= Encoding.UTF8);
var buffer = (char[]?)null;

try
{
cancellationToken.ThrowIfCancellationRequested();

buffer = ArrayPool<char>.Shared.Rent(encoding.GetMaxCharCount(BufferSize));
var sb = new StringBuilder();

while (true)
{
var count = await reader
.ReadAsync(new Memory<char>(buffer), cancellationToken)
.ConfigureAwait(false);

if (count == 0)
return sb.ToString();

sb.Append(buffer.AsSpan(0, count));
}
}
finally
{
reader.Dispose();
// ReSharper disable once UseAwaitUsing
using var stream = file.OpenRead();
using var reader = new StreamReader(stream, encoding!);

if (buffer is not null)
ArrayPool<char>.Shared.Return(buffer);
}
return await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -211,15 +184,13 @@ public static ValueTask<string[]> ReadAllLinesAsync(this IFileInfo file, Cancell
/// </returns>
public static async ValueTask<string[]> ReadAllLinesAsync(this IFileInfo file, Encoding? encoding, CancellationToken cancellationToken = default)
{
var stream = file.OpenRead();
// ReSharper disable once UseAwaitUsing
using var stream = file.OpenRead();
using var reader = new StreamReader(stream, encoding!);

var list = new List<string>();
while (await reader.ReadLineAsync().ConfigureAwait(false) is { } line)
{
cancellationToken.ThrowIfCancellationRequested();
while (await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false) is { } line)
list.Add(line);
}

return list.ToArray();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#if NET6_0
using System.Buffers;
using System.Text;

// ReSharper disable once CheckNamespace
namespace System.IO;
/// <summary>
/// Provides extension methods for the <see cref="StreamReader"/> to offer API compatibility with newer .NET versions.
/// </summary>
internal static class StreamReaderExtensions
{
/// <summary>
/// Reads a line of characters asynchronously from the current stream and returns the data as a string.
/// </summary>
/// <param name="reader">The <see cref="StreamReader"/> to read from.</param>
/// <param name="cancellationToken">An optional cancellation token to cancel the operation.</param>
/// <returns>
/// A <see cref="ValueTask{TResult}"/> that represents the asynchronous read operation.
/// The value of the task contains the next line from the stream, or is <see langword="null"/>
/// if the end of the stream is reached.
/// </returns>
public static ValueTask<string?> ReadLineAsync(this StreamReader reader, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
return ValueTask.FromCanceled<string?>(cancellationToken);

return new ValueTask<string?>(reader.ReadLineAsync());
}

/// <summary>
/// Reads all characters from the current position to the end of the stream asynchronously and returns them as one string.
/// </summary>
/// <param name="reader">The <see cref="StreamReader"/> to read from.</param>
/// <param name="cancellationToken">An optional cancellation token to cancel the operation.</param>
/// <returns>
/// A <see cref="Task{TResult}"/> that represents the asynchronous read operation.
/// The value of the task contains a string with the characters from the current position to the end of the stream.
/// </returns>
public static async Task<string> ReadToEndAsync(this StreamReader reader, CancellationToken cancellationToken = default)
{
const int BufferSize = 4096;

var chars = ArrayPool<char>.Shared.Rent(BufferSize);
var sb = new StringBuilder();

while (true)
{
var count = await reader
.ReadAsync(new Memory<char>(chars), cancellationToken)
.ConfigureAwait(false);

if (count == 0)
break;

sb.Append(chars.AsSpan(0, count));
}

ArrayPool<char>.Shared.Return(chars);
return sb.ToString();
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<Description>A lightweight .NET library of useful and convenient extensions for IFileProvider.</Description>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand Down Expand Up @@ -36,8 +36,15 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" VersionOverride="8.0.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand All @@ -63,7 +70,7 @@
</ItemGroup>

<ItemGroup>
<None Update="README.md">
<None Include="README.md">
<Link>Properties\README.md</Link>
<Pack>True</Pack>
<PackagePath>\</PackagePath>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
Expand Down
Loading