|
|
@@ -0,0 +1,163 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace Quadarax.Application.Tools.Vsix.FilteredSolutionsExtension
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// Provides async file operations compatible with .NET 4.7.2
|
|
|
+ /// Implements File.ReadAllTextAsync and File.WriteAllTextAsync functionality
|
|
|
+ /// </summary>
|
|
|
+ public static class FileUtils
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously reads all text from a file using UTF-8 encoding
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to read from</param>
|
|
|
+ /// <returns>A task that represents the asynchronous read operation</returns>
|
|
|
+ public static Task<string> ReadAllTextAsync(string path)
|
|
|
+ {
|
|
|
+ return ReadAllTextAsync(path, Encoding.UTF8);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously reads all text from a file using the specified encoding
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to read from</param>
|
|
|
+ /// <param name="encoding">The encoding to use</param>
|
|
|
+ /// <returns>A task that represents the asynchronous read operation</returns>
|
|
|
+ public static Task<string> ReadAllTextAsync(string path, Encoding encoding)
|
|
|
+ {
|
|
|
+ return ReadAllTextAsync(path, encoding, CancellationToken.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously reads all text from a file using the specified encoding and cancellation token
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to read from</param>
|
|
|
+ /// <param name="encoding">The encoding to use</param>
|
|
|
+ /// <param name="cancellationToken">The cancellation token</param>
|
|
|
+ /// <returns>A task that represents the asynchronous read operation</returns>
|
|
|
+ public static async Task<string> ReadAllTextAsync(string path, Encoding encoding, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ if (path == null)
|
|
|
+ throw new ArgumentNullException(nameof(path));
|
|
|
+ if (encoding == null)
|
|
|
+ throw new ArgumentNullException(nameof(encoding));
|
|
|
+
|
|
|
+ using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
|
|
|
+ using (var streamReader = new StreamReader(fileStream, encoding))
|
|
|
+ {
|
|
|
+ return await streamReader.ReadToEndAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously writes text to a file using UTF-8 encoding
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to write to</param>
|
|
|
+ /// <param name="contents">The text content to write</param>
|
|
|
+ /// <returns>A task that represents the asynchronous write operation</returns>
|
|
|
+ public static Task WriteAllTextAsync(string path, string contents)
|
|
|
+ {
|
|
|
+ return WriteAllTextAsync(path, contents, Encoding.UTF8);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously writes text to a file using the specified encoding
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to write to</param>
|
|
|
+ /// <param name="contents">The text content to write</param>
|
|
|
+ /// <param name="encoding">The encoding to use</param>
|
|
|
+ /// <returns>A task that represents the asynchronous write operation</returns>
|
|
|
+ public static Task WriteAllTextAsync(string path, string contents, Encoding encoding)
|
|
|
+ {
|
|
|
+ return WriteAllTextAsync(path, contents, encoding, CancellationToken.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously writes text to a file using the specified encoding and cancellation token
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to write to</param>
|
|
|
+ /// <param name="contents">The text content to write</param>
|
|
|
+ /// <param name="encoding">The encoding to use</param>
|
|
|
+ /// <param name="cancellationToken">The cancellation token</param>
|
|
|
+ /// <returns>A task that represents the asynchronous write operation</returns>
|
|
|
+ public static async Task WriteAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ if (path == null)
|
|
|
+ throw new ArgumentNullException(nameof(path));
|
|
|
+ if (contents == null)
|
|
|
+ throw new ArgumentNullException(nameof(contents));
|
|
|
+ if (encoding == null)
|
|
|
+ throw new ArgumentNullException(nameof(encoding));
|
|
|
+
|
|
|
+ using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, useAsync: true))
|
|
|
+ using (var streamWriter = new StreamWriter(fileStream, encoding))
|
|
|
+ {
|
|
|
+ await streamWriter.WriteAsync(contents).ConfigureAwait(false);
|
|
|
+ await streamWriter.FlushAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously reads all bytes from a file
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to read from</param>
|
|
|
+ /// <returns>A task that represents the asynchronous read operation</returns>
|
|
|
+ public static async Task<byte[]> ReadAllBytesAsync(string path)
|
|
|
+ {
|
|
|
+ if (path == null)
|
|
|
+ throw new ArgumentNullException(nameof(path));
|
|
|
+
|
|
|
+ using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
|
|
|
+ {
|
|
|
+ var buffer = new byte[fileStream.Length];
|
|
|
+ var totalBytesRead = 0;
|
|
|
+ var bytesRead = 0;
|
|
|
+
|
|
|
+ while (totalBytesRead < buffer.Length)
|
|
|
+ {
|
|
|
+ bytesRead = await fileStream.ReadAsync(buffer, totalBytesRead, buffer.Length - totalBytesRead).ConfigureAwait(false);
|
|
|
+ if (bytesRead == 0)
|
|
|
+ break;
|
|
|
+ totalBytesRead += bytesRead;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (totalBytesRead != buffer.Length)
|
|
|
+ {
|
|
|
+ // File size changed during read, resize array
|
|
|
+ var resizedBuffer = new byte[totalBytesRead];
|
|
|
+ Array.Copy(buffer, resizedBuffer, totalBytesRead);
|
|
|
+ return resizedBuffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ return buffer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Asynchronously writes bytes to a file
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path">The file path to write to</param>
|
|
|
+ /// <param name="bytes">The bytes to write</param>
|
|
|
+ /// <returns>A task that represents the asynchronous write operation</returns>
|
|
|
+ public static async Task WriteAllBytesAsync(string path, byte[] bytes)
|
|
|
+ {
|
|
|
+ if (path == null)
|
|
|
+ throw new ArgumentNullException(nameof(path));
|
|
|
+ if (bytes == null)
|
|
|
+ throw new ArgumentNullException(nameof(bytes));
|
|
|
+
|
|
|
+ using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, useAsync: true))
|
|
|
+ {
|
|
|
+ await fileStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
|
|
|
+ await fileStream.FlushAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|