diff --git a/GitVersion.yml b/GitVersion.yml
index c967cdc..d4b60a2 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -1,4 +1,4 @@
-next-version: 1.1.0
+next-version: 1.1.5
tag-prefix: '[vV]'
mode: ContinuousDeployment
branches:
diff --git a/README.md b/README.md
index d9e0d8a..161d8b0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-#
Parsley.Net v1.1.0
+#
Parsley.Net v1.1.5
[](https://badge.fury.io/nu/Parsley.Net) [](https://github.com/CodeShayk/Parsley.Net/blob/master/LICENSE.md)
[](https://github.com/CodeShayk/Parsley.Net/releases/latest)
[](https://github.com/CodeShayk/parsley.net/actions/workflows/Master-Build.yml)
@@ -44,9 +44,9 @@ NuGet\Install-Package Parsley.Net
Please see below.
```
- public interface IParser
- {
- ///
+ public interface IParser
+ {
+ ///
/// Parses a file at the specified filepath into an array of objects of type T.
///
///
@@ -63,20 +63,20 @@ Please see below.
T[] Parse(string[] lines) where T : IFileLine, new();
///
- /// Parses a stream of delimiter separated records into an array of objects of type T.
+ /// Parses an array of bytes of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- T[] Parse(Stream stream) where T : IFileLine, new();
+ T[] Parse(byte[] bytes, Encoding encoding = null) where T : IFileLine, new();
///
- /// Parses an array of bytes of delimiter separated records into an array of objects of type T.
+ /// Parses a stream of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- T[] Parse(byte[] bytes) where T : IFileLine, new();
+ T[] Parse(Stream stream, Encoding encoding = null) where T : IFileLine, new();
///
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
@@ -95,20 +95,21 @@ Please see below.
Task ParseAsync(string[] lines) where T : IFileLine, new();
///
- /// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
+ /// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- Task ParseAsync(Stream stream) where T : IFileLine, new();
+ Task ParseAsync(byte[] bytes, Encoding encoding = null) where T : IFileLine, new();
+
///
- /// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
+ /// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
///
///
- ///
+ ///
///
- Task ParseAsync(byte[] bytes) where T : IFileLine, new();
- }
+ Task ParseAsync(Stream stream, Encoding encoding = null) where T : IFileLine, new();
+ }
```
To initialise `Parser` class you could do it manually or use dependency injection as shown below. The parser class has parameterised constructor that takes the delimiter character to initialise the instance. Default character is ',' (comma) to initialise the parser for a CSV file parsing.
@@ -338,6 +339,7 @@ The main branch is now on .NET 9.0.
| -------- | --------|
| [`v1.0.0`](https://github.com/CodeShayk/parsley.net/tree/v1.0.0) | [Notes](https://github.com/CodeShayk/Parsley.Net/releases/tag/v1.0.0) |
| [`v1.1.0`](https://github.com/CodeShayk/parsley.net/tree/v1.1.0) | [Notes](https://github.com/CodeShayk/Parsley.Net/releases/tag/v1.1.0) |
+| [`v1.1.5`](https://github.com/CodeShayk/parsley.net/tree/v1.1.5) | [Notes](https://github.com/CodeShayk/Parsley.Net/releases/tag/v1.1.5) |
## Credits
Thank you for reading. Please fork, explore, contribute and report. Happy Coding !! :)
diff --git a/src/Parsley/IParser.cs b/src/Parsley/IParser.cs
index 6bba956..365089c 100644
--- a/src/Parsley/IParser.cs
+++ b/src/Parsley/IParser.cs
@@ -1,4 +1,5 @@
using System.IO;
+using System.Text;
using System.Threading.Tasks;
namespace parsley
@@ -19,23 +20,23 @@ public interface IParser
///
///
///
- T[] Parse(string[] lines) where T : IFileLine, new();
-
+ T[] Parse(string[] lines) where T : IFileLine, new();
+
///
- /// Parses a stream of delimiter separated records into an array of objects of type T.
+ /// Parses an array of bytes of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- T[] Parse(Stream stream) where T : IFileLine, new();
-
+ T[] Parse(byte[] bytes, Encoding encoding = null) where T : IFileLine, new();
+
///
- /// Parses an array of bytes of delimiter separated records into an array of objects of type T.
+ /// Parses a stream of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- T[] Parse(byte[] bytes) where T : IFileLine, new();
+ T[] Parse(Stream stream, Encoding encoding = null) where T : IFileLine, new();
///
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
@@ -52,21 +53,21 @@ public interface IParser
///
///
Task ParseAsync(string[] lines) where T : IFileLine, new();
-
+
///
- /// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
+ /// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
///
///
- ///
+ ///
///
- Task ParseAsync(Stream stream) where T : IFileLine, new();
-
+ Task ParseAsync(byte[] bytes, Encoding encoding = null) where T : IFileLine, new();
+
///
- /// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
+ /// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
///
///
- ///
+ ///
///
- Task ParseAsync(byte[] bytes) where T : IFileLine, new();
+ Task ParseAsync(Stream stream, Encoding encoding = null) where T : IFileLine, new();
}
}
\ No newline at end of file
diff --git a/src/Parsley/Parser.cs b/src/Parsley/Parser.cs
index 2696b67..aa6bb1e 100644
--- a/src/Parsley/Parser.cs
+++ b/src/Parsley/Parser.cs
@@ -68,16 +68,8 @@ public Parser(char delimiter)
}
private string[] ReadToLines(string path)
- {
- var lines = new List();
-
- foreach (var line in File.ReadLines(path))
- {
- if (line != null)
- lines.Add(line);
- }
-
- return lines.ToArray();
+ {
+ return File.ReadAllLines(path);
}
private T ParseLine(string line) where T : IFileLine, new()
@@ -165,13 +157,13 @@ private string[] GetDelimiterSeparatedValues(string line)
return values;
}
- public T[] Parse(Stream stream) where T : IFileLine, new()
+ public T[] Parse(Stream stream, Encoding encoding = null) where T : IFileLine, new()
{
if (stream == null || stream.Length == 0)
return Array.Empty();
var lines = new List();
- using (var reader = new StreamReader(stream, Encoding.UTF8))
+ using (var reader = new StreamReader(stream, encoding ?? Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
@@ -186,12 +178,12 @@ private string[] GetDelimiterSeparatedValues(string line)
return lines.Any() ? Parse(lines.ToArray()) : Array.Empty();
}
- public T[] Parse(byte[] bytes) where T : IFileLine, new()
+ public T[] Parse(byte[] bytes, Encoding encoding = null) where T : IFileLine, new()
{
if (bytes == null || bytes.Length == 0)
return Array.Empty();
- return Parse(new MemoryStream(bytes));
+ return Parse(new MemoryStream(bytes), encoding);
}
public async Task ParseAsync(string filepath) where T : IFileLine, new()
@@ -199,40 +191,23 @@ private string[] GetDelimiterSeparatedValues(string line)
if (string.IsNullOrEmpty(filepath) || !File.Exists(filepath))
return Array.Empty();
- var lines = await Task.Run(() => ReadToLines(filepath));
+ var lines = await Task.FromResult(ReadToLines(filepath));
return await ParseAsync(lines);
- }
-
- public async Task ParseAsync(string[] lines) where T : IFileLine, new()
+ }
+
+ public async Task ParseAsync(byte[] bytes, Encoding encoding = null) where T : IFileLine, new()
{
- if (lines == null || lines.Length == 0)
+ if (bytes == null || bytes.Length == 0)
return Array.Empty();
- var list = new T[lines.Length];
- var index = 0;
- var inputs = lines.Select(line => new { Line = line, Index = index++ });
-
- foreach (var input in inputs)
- {
- if (string.IsNullOrWhiteSpace(input.Line))
- continue;
-
- var parsedLine = await Task.Run(() => ParseLine(input.Line));
+ return await ParseAsync(new MemoryStream(bytes), encoding);
+ }
- if (parsedLine != null)
- {
- parsedLine.Index = input.Index;
- list[parsedLine.Index] = parsedLine;
- }
- }
- return list;
- }
-
- public async Task ParseAsync(Stream stream) where T : IFileLine, new()
+ public async Task ParseAsync(Stream stream, Encoding encoding = null) where T : IFileLine, new()
{
var lines = new List();
- using (var reader = new StreamReader(stream, Encoding.UTF8))
+ using (var reader = new StreamReader(stream, encoding ?? Encoding.UTF8))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
@@ -244,14 +219,30 @@ private string[] GetDelimiterSeparatedValues(string line)
}
return lines.Any() ? await ParseAsync(lines.ToArray()) : Array.Empty();
- }
+ }
- public async Task ParseAsync(byte[] bytes) where T : IFileLine, new()
+ public async Task ParseAsync(string[] lines) where T : IFileLine, new()
{
- if (bytes == null || bytes.Length == 0)
+ if (lines == null || lines.Length == 0)
return Array.Empty();
- return await ParseAsync(new MemoryStream(bytes));
+ var index = 0;
+ var indexedLines = lines
+ .Select((line) => new { Line = line, Index = index++ })
+ .Where(x => !string.IsNullOrWhiteSpace(x.Line))
+ .ToArray();
+
+ var tasks = indexedLines
+ .Select(x => Task.Run(() => new { x.Index, Parsed = ParseLine(x.Line) }))
+ .ToArray();
+
+ var results = await Task.WhenAll(tasks);
+
+ var list = new T[tasks.Length];
+ foreach (var result in results)
+ list[result.Index] = result.Parsed;
+
+ return list;
}
}
}
\ No newline at end of file
diff --git a/src/Parsley/Parsley.csproj b/src/Parsley/Parsley.csproj
index f4048fb..cf61c1a 100644
--- a/src/Parsley/Parsley.csproj
+++ b/src/Parsley/Parsley.csproj
@@ -19,11 +19,8 @@
True
https://github.com/CodeShayk/Parsley.Net/wiki
https://github.com/CodeShayk/Parsley.Net
-
- v1.1.0 - Targets .Net9.0, .NetStandard2.1, .NetStandard2.0, and .NetFramework4.6.4.
-* Includes core functionality for parsing delimiter separated files.
-* Provided Sync and Async parsing methods
- 1.1.0
+ v1.1.5 - performance improvements in async parsing.
+ 1.1.5
True
Parsley.Net
diff --git a/tests/Parsley.Tests/ParserFixture.cs b/tests/Parsley.Tests/ParserFixture.cs
index 1254b31..7ceab43 100644
--- a/tests/Parsley.Tests/ParserFixture.cs
+++ b/tests/Parsley.Tests/ParserFixture.cs
@@ -39,7 +39,7 @@ public void TestParseForDependencyInjectionShouldReturnInitialisedInstance()
}
[Test]
- public void TestParseWithFileInputShouldReturnCorrectlyParsedArray()
+ public void TestParseWithFilePathShouldReturnCorrectlyParsedArray()
{
var filePath = Path.Combine(Environment.CurrentDirectory, "TestFile.txt");
@@ -221,14 +221,15 @@ public async Task TestParseAsyncWithStringArrayInputShouldReturnCorrectlyParsedA
var lines = new[]
{
"GB-01|Bob Marley|True|Free",
- "UH-02|John Walsh McKinsey|False|Paid"
+ "UH-02|John Walsh McKinsey|False|Paid",
+ "UH-03|Fred Wigg|False|Paid",
};
parser = new Parser('|');
var parsed = await parser.ParseAsync(lines);
- Assert.That(parsed.Length, Is.EqualTo(2));
+ Assert.That(parsed.Length, Is.EqualTo(3));
Assert.That(parsed[0].Code.Batch, Is.EqualTo("GB"));
Assert.That(parsed[0].Code.SerialNo, Is.EqualTo(1));