Skip to content

Commit

Permalink
Add convenience methods to read and write text
Browse files Browse the repository at this point in the history
  • Loading branch information
patriksvensson committed Jul 1, 2024
1 parent dd90034 commit 8395100
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 87 deletions.
39 changes: 1 addition & 38 deletions src/Spectre.IO.Testing/Extensions/FakeFileExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,38 +55,13 @@ public static FakeFile SetTextContent(this FakeFile file, string content, Encodi
}
}

/// <summary>
/// Gets the binary content of the specified file.
/// </summary>
/// <param name="file">The file.</param>
/// <returns>The binary content of the specified file.</returns>
public static byte[] GetBinaryContent(this FakeFile file)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}

if (!file.Exists)
{
throw new FileNotFoundException("File could not be found.", file.Path.FullPath);
}

using (var stream = file.OpenRead())
using (var reader = new BinaryReader(stream))
using (var memory = new MemoryStream())
{
reader.BaseStream.CopyTo(memory);
return memory.ToArray();
}
}

/// <summary>
/// Gets the text content of the file.
/// </summary>
/// <param name="file">The file.</param>
/// <param name="encoding">The text encoding to use, or <c>null</c> to use the default encoding.</param>
/// <returns>The text content of the file.</returns>
[Obsolete("Use `IFile.ReadAllText(...)` instead")]
public static string GetTextContent(this FakeFile file, Encoding? encoding = null)
{
if (file == null)
Expand All @@ -108,18 +83,6 @@ public static string GetTextContent(this FakeFile file, Encoding? encoding = nul
}
}

/// <summary>
/// Determines if a specified file has a UTF-8 BOM.
/// </summary>
/// <param name="file">The file.</param>
/// <returns>Whether or not the specified file has a UTF-8 BOM.</returns>
public static bool HasUTF8BOM(this FakeFile file)
{
var content = GetBinaryContent(file);
var preamble = Encoding.UTF8.GetPreamble();
return content.StartsWith(preamble);
}

/// <summary>
/// Hides the specified file.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Spectre.IO.Tests/Unit/Fakes/FakeFileSystemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void Should_Return_Content_Of_Original_File()
fileSystem.File.CreateSymbolicLink("/Working/test.txt", "/home/Patrik/foo.txt");

// When
var result = fileSystem.GetFakeFile("/home/Patrik/foo.txt").GetTextContent();
var result = fileSystem.GetFakeFile("/home/Patrik/foo.txt").ReadAllText();

// Then
result.ShouldBe("LOL");
Expand Down
28 changes: 0 additions & 28 deletions src/Spectre.IO.Tests/Unit/FileSystemExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ public sealed class TheExistMethod
{
public sealed class WithFilePath
{
[Fact]
public void Should_Return_False_If_File_System_Returned_Null()
{
// Given
var fileSystem = Substitute.For<IFileSystem>();
fileSystem.File.Retrieve(Arg.Any<FilePath>()).Returns((IFile)null);

// When
var result = fileSystem.Exist((FilePath)"file.txt");

// Then
result.ShouldBeFalse();
}

[Fact]
public void Should_Return_False_If_File_Do_Not_Exist()
{
Expand Down Expand Up @@ -71,20 +57,6 @@ public void Should_Throw_If_FileSystem_Is_Null()

public sealed class WithDirectoryPath
{
[Fact]
public void Should_Return_False_If_File_System_Returned_Null()
{
// Given
var fileSystem = Substitute.For<IFileSystem>();
fileSystem.Directory.Retrieve(Arg.Any<DirectoryPath>()).Returns((IDirectory)null);

// When
var result = fileSystem.Exist((DirectoryPath)"/Target");

// Then
result.ShouldBeFalse();
}

[Fact]
public void Should_Return_False_If_Directory_Do_Not_Exist()
{
Expand Down
70 changes: 54 additions & 16 deletions src/Spectre.IO/Extensions/IFileExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;

namespace Spectre.IO;

Expand All @@ -17,10 +18,7 @@ public static class IFileExtensions
/// <returns>A <see cref="Stream"/> to the file.</returns>
public static Stream Open(this IFile file, FileMode mode)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}
ArgumentNullException.ThrowIfNull(file);

return file.Open(
mode,
Expand All @@ -37,10 +35,7 @@ public static Stream Open(this IFile file, FileMode mode)
/// <returns>A <see cref="Stream"/> to the file.</returns>
public static Stream Open(this IFile file, FileMode mode, FileAccess access)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}
ArgumentNullException.ThrowIfNull(file);

return file.Open(mode, access, FileShare.None);
}
Expand All @@ -52,10 +47,7 @@ public static Stream Open(this IFile file, FileMode mode, FileAccess access)
/// <returns>A <see cref="Stream"/> to the file.</returns>
public static Stream OpenRead(this IFile file)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}
ArgumentNullException.ThrowIfNull(file);

return file.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
}
Expand All @@ -68,10 +60,7 @@ public static Stream OpenRead(this IFile file)
/// <returns>A <see cref="Stream"/> to the file.</returns>
public static Stream OpenWrite(this IFile file)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}
ArgumentNullException.ThrowIfNull(file);

return file.Open(FileMode.Create, FileAccess.Write, FileShare.None);
}
Expand All @@ -86,6 +75,9 @@ public static Stream OpenWrite(this IFile file)
/// <returns>Whether or not the operation succeeded.</returns>
public static bool TryCopy(this IFile file, FilePath destination, bool overwrite, out IFile? result)
{
ArgumentNullException.ThrowIfNull(file);
ArgumentNullException.ThrowIfNull(destination);

try
{
result = file.Copy(destination, overwrite);
Expand All @@ -107,6 +99,9 @@ public static bool TryCopy(this IFile file, FilePath destination, bool overwrite
/// <returns>Whether or not the operation succeeded.</returns>
public static bool TryMove(this IFile file, FilePath destination, [NotNullWhen(true)] out IFile? result)
{
ArgumentNullException.ThrowIfNull(file);
ArgumentNullException.ThrowIfNull(destination);

return TryMove(file, destination, false, out result);
}

Expand All @@ -124,6 +119,9 @@ public static bool TryMove(
bool overwrite,
[NotNullWhen(true)] out IFile? result)
{
ArgumentNullException.ThrowIfNull(file);
ArgumentNullException.ThrowIfNull(destination);

try
{
result = file.Move(destination, overwrite);
Expand All @@ -143,6 +141,8 @@ public static bool TryMove(
/// <returns>Whether or not the operation succeeded.</returns>
public static bool TryDelete(this IFile file)
{
ArgumentNullException.ThrowIfNull(file);

try
{
file.Delete();
Expand All @@ -153,4 +153,42 @@ public static bool TryDelete(this IFile file)
return false;
}
}

/// <summary>
/// Opens a text file, reads all the text in the file, and then closes the file.
/// </summary>
/// <param name="file">The file to read from.</param>
/// <param name="encoding">The character encoding to use.</param>
/// <returns>A string containing all text in the file.</returns>
public static string ReadAllText(
this IFile file,
Encoding? encoding = null)
{
ArgumentNullException.ThrowIfNull(file);

using (var reader = new StreamReader(file.OpenRead(), encoding, true, -1, false))
{
return reader.ReadToEnd();
}
}

/// <summary>
/// Creates a new file, writes the specified string to the file, and then closes the file.
/// If the target file already exists, it is overwritten.
/// </summary>
/// <param name="file">The file to write to.</param>
/// <param name="contents">The string to write to the file.</param>
/// <param name="encoding">The encoding to apply to the string.</param>
public static void WriteAllText(
this IFile file,
string contents,
Encoding? encoding = null)
{
ArgumentNullException.ThrowIfNull(file);

using (var writer = new StreamWriter(file.OpenWrite(), encoding, -1, false))
{
writer.Write(contents);
}
}
}
55 changes: 51 additions & 4 deletions src/Spectre.IO/Extensions/IFileSystemExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.IO;
using System.Text;

namespace Spectre.IO;

Expand Down Expand Up @@ -52,8 +54,7 @@ public static bool Exist(this IFileSystem fileSystem, FilePath path)
throw new ArgumentNullException(nameof(fileSystem));
}

var file = fileSystem.File.Retrieve(path);
return file?.Exists == true;
return GetFile(fileSystem, path).Exists;
}

/// <summary>
Expand All @@ -69,7 +70,53 @@ public static bool Exist(this IFileSystem fileSystem, DirectoryPath path)
throw new ArgumentNullException(nameof(fileSystem));
}

var directory = fileSystem.Directory.Retrieve(path);
return directory?.Exists == true;
return GetDirectory(fileSystem, path).Exists;
}

/// <summary>
/// Opens a text file, reads all the text in the file, and then closes the file.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="path">The file path to read from.</param>
/// <param name="encoding">The character encoding to use.</param>
/// <returns>A string containing all text in the file.</returns>
public static string ReadAllText(
this IFileSystem fileSystem,
FilePath path,
Encoding? encoding = null)
{
ArgumentNullException.ThrowIfNull(fileSystem);
ArgumentNullException.ThrowIfNull(path);

var file = GetFile(fileSystem, path);
using (var reader = new StreamReader(file.OpenRead(), encoding, true, -1, false))
{
return reader.ReadToEnd();
}
}

/// <summary>
/// Creates a new file, writes the specified string to the file, and then closes the file.
/// If the target file already exists, it is overwritten.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="path">The file path to write to.</param>
/// <param name="contents">The string to write to the file.</param>
/// <param name="encoding">The encoding to apply to the string.</param>
public static void WriteAllText(
this IFileSystem fileSystem,
FilePath path,
string contents,
Encoding? encoding = null)
{
ArgumentNullException.ThrowIfNull(fileSystem);
ArgumentNullException.ThrowIfNull(path);
ArgumentNullException.ThrowIfNull(contents);

var file = GetFile(fileSystem, path);
using (var writer = new StreamWriter(file.OpenWrite(), encoding, -1, false))
{
writer.Write(contents);
}
}
}

0 comments on commit 8395100

Please sign in to comment.