Skip to content

Commit

Permalink
feat: Add EnumerateLines extension method (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
gigi81 authored Aug 20, 2023
1 parent e5c61b5 commit d169c4d
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace System.IO.Abstractions
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace System.IO.Abstractions
{
public static class IFileInfoExtensions
{
Expand All @@ -12,5 +16,26 @@ public static void ThrowIfNotFound(this IFileInfo info)
if (!info.Exists)
throw new FileNotFoundException(StringResources.Format("COULD_NOT_FIND_FILE_EXCEPTION", info.FullName));
}

/// <summary>
/// Creates an <see cref="IEnumerable{String}"/> that can enumerate the lines of text in the <paramref name="info"/> file
/// </summary>
/// <param name="info">File to enumerate content</param>
/// <returns>Returns an <see cref="IEnumerable{String}"/> to enumerate the content of the file</returns>
public static IEnumerable<string> EnumerateLines(this IFileInfo info)
{
return new LineEnumerable(info, null);
}

/// <summary>
/// Creates an <see cref="IEnumerable{String}"/> that can enumerate the lines of text in the <paramref name="info"/> file
/// using the specified <paramref name="encoding"/>
/// </summary>
/// <param name="info">File to enumerate content</param>
/// <returns>Returns an <see cref="IEnumerable{String}"/> to enumerate the content of the file</returns>
public static IEnumerable<string> EnumerateLines(this IFileInfo info, Encoding encoding)
{
return new LineEnumerable(info, encoding);
}
}
}
60 changes: 60 additions & 0 deletions src/System.IO.Abstractions.Extensions/LineEnumerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace System.IO.Abstractions
{
internal sealed class LineEnumerable : IEnumerable<string>
{
private readonly IFileInfo _file;
private readonly Encoding _encoding;

public LineEnumerable(IFileInfo file, Encoding encoding)
{
_file = file;
_encoding = encoding;
}

public IEnumerator<string> GetEnumerator() => new LineEnumerator(_file, _encoding);

IEnumerator IEnumerable.GetEnumerator() => new LineEnumerator(_file, _encoding);
}

internal sealed class LineEnumerator : IEnumerator<string>
{
private Stream _stream;
private StreamReader _reader;
private string _current;

public LineEnumerator(IFileInfo file, Encoding encoding)
{
_stream = file.OpenRead();
_reader = encoding == null
? new StreamReader(_stream)
: new StreamReader(_stream, encoding);
}

public string Current => _current;

object IEnumerator.Current => _current;

public void Dispose()
{
_reader?.Dispose();
_reader = null;
_stream?.Dispose();
_stream = null;
}

public bool MoveNext()
{
_current = _reader.ReadLine();
return _current != null;
}

public void Reset()
{
throw new InvalidOperationException();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.IO.Abstractions.Extensions.Tests
{
Expand Down Expand Up @@ -43,5 +46,33 @@ public void ThrowIfNotFound_IfFileExists_DoesNotThrowException()
//cleanup
file.Delete();
}

[TestCase("line1", "line2", "line3")]
[TestCase("line1", "", "line3")]
public void EnumerateLines_ReadFromExistingFile_ReturnsLines(params string[] content)
{
//arrange
var fs = new FileSystem();
var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
var guid = Guid.NewGuid().ToString();
var file = current.File(guid);
//create file
using (var stream = file.OpenWrite())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
foreach(var line in content)
writer.WriteLine(line);
}

//act
var actual = file.EnumerateLines().ToArray();

//assert
Assert.AreEqual(content.Length, actual.Length);
for(int i=0; i<content.Length; i++)
{
Assert.AreEqual(content[i], actual[i]);
}
}
}
}

0 comments on commit d169c4d

Please sign in to comment.