Skip to content

Commit d169c4d

Browse files
authored
feat: Add EnumerateLines extension method (#45)
1 parent e5c61b5 commit d169c4d

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
namespace System.IO.Abstractions
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace System.IO.Abstractions
26
{
37
public static class IFileInfoExtensions
48
{
@@ -12,5 +16,26 @@ public static void ThrowIfNotFound(this IFileInfo info)
1216
if (!info.Exists)
1317
throw new FileNotFoundException(StringResources.Format("COULD_NOT_FIND_FILE_EXCEPTION", info.FullName));
1418
}
19+
20+
/// <summary>
21+
/// Creates an <see cref="IEnumerable{String}"/> that can enumerate the lines of text in the <paramref name="info"/> file
22+
/// </summary>
23+
/// <param name="info">File to enumerate content</param>
24+
/// <returns>Returns an <see cref="IEnumerable{String}"/> to enumerate the content of the file</returns>
25+
public static IEnumerable<string> EnumerateLines(this IFileInfo info)
26+
{
27+
return new LineEnumerable(info, null);
28+
}
29+
30+
/// <summary>
31+
/// Creates an <see cref="IEnumerable{String}"/> that can enumerate the lines of text in the <paramref name="info"/> file
32+
/// using the specified <paramref name="encoding"/>
33+
/// </summary>
34+
/// <param name="info">File to enumerate content</param>
35+
/// <returns>Returns an <see cref="IEnumerable{String}"/> to enumerate the content of the file</returns>
36+
public static IEnumerable<string> EnumerateLines(this IFileInfo info, Encoding encoding)
37+
{
38+
return new LineEnumerable(info, encoding);
39+
}
1540
}
1641
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace System.IO.Abstractions
6+
{
7+
internal sealed class LineEnumerable : IEnumerable<string>
8+
{
9+
private readonly IFileInfo _file;
10+
private readonly Encoding _encoding;
11+
12+
public LineEnumerable(IFileInfo file, Encoding encoding)
13+
{
14+
_file = file;
15+
_encoding = encoding;
16+
}
17+
18+
public IEnumerator<string> GetEnumerator() => new LineEnumerator(_file, _encoding);
19+
20+
IEnumerator IEnumerable.GetEnumerator() => new LineEnumerator(_file, _encoding);
21+
}
22+
23+
internal sealed class LineEnumerator : IEnumerator<string>
24+
{
25+
private Stream _stream;
26+
private StreamReader _reader;
27+
private string _current;
28+
29+
public LineEnumerator(IFileInfo file, Encoding encoding)
30+
{
31+
_stream = file.OpenRead();
32+
_reader = encoding == null
33+
? new StreamReader(_stream)
34+
: new StreamReader(_stream, encoding);
35+
}
36+
37+
public string Current => _current;
38+
39+
object IEnumerator.Current => _current;
40+
41+
public void Dispose()
42+
{
43+
_reader?.Dispose();
44+
_reader = null;
45+
_stream?.Dispose();
46+
_stream = null;
47+
}
48+
49+
public bool MoveNext()
50+
{
51+
_current = _reader.ReadLine();
52+
return _current != null;
53+
}
54+
55+
public void Reset()
56+
{
57+
throw new InvalidOperationException();
58+
}
59+
}
60+
}

tests/System.IO.Abstractions.Extensions.Tests/FileInfoExtensionsTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
using NUnit.Framework;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
25

36
namespace System.IO.Abstractions.Extensions.Tests
47
{
@@ -43,5 +46,33 @@ public void ThrowIfNotFound_IfFileExists_DoesNotThrowException()
4346
//cleanup
4447
file.Delete();
4548
}
49+
50+
[TestCase("line1", "line2", "line3")]
51+
[TestCase("line1", "", "line3")]
52+
public void EnumerateLines_ReadFromExistingFile_ReturnsLines(params string[] content)
53+
{
54+
//arrange
55+
var fs = new FileSystem();
56+
var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
57+
var guid = Guid.NewGuid().ToString();
58+
var file = current.File(guid);
59+
//create file
60+
using (var stream = file.OpenWrite())
61+
using (var writer = new StreamWriter(stream, Encoding.UTF8))
62+
{
63+
foreach(var line in content)
64+
writer.WriteLine(line);
65+
}
66+
67+
//act
68+
var actual = file.EnumerateLines().ToArray();
69+
70+
//assert
71+
Assert.AreEqual(content.Length, actual.Length);
72+
for(int i=0; i<content.Length; i++)
73+
{
74+
Assert.AreEqual(content[i], actual[i]);
75+
}
76+
}
4677
}
4778
}

0 commit comments

Comments
 (0)