Skip to content

Commit

Permalink
Added "ExportAsMemoryStream", less allocations in file export
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-jitbit committed Jun 5, 2024
1 parent 0aa6b96 commit f3a18a1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 23 deletions.
55 changes: 32 additions & 23 deletions CsvExport/CsvExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,43 +229,52 @@ public string Export()
/// </summary>
public void ExportToFile(string path, Encoding encoding = null)
{
File.WriteAllBytes(path, ExportToBytes(encoding ?? _defaultEncoding));
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
using var ms = ExportAsMemoryStream(encoding);
ms.WriteTo(fs);
}

/// <summary>
/// Exports as raw bytes.
/// </summary>
public byte[] ExportToBytes(Encoding encoding = null)
{
using (MemoryStream ms = new MemoryStream())
{
encoding = encoding ?? _defaultEncoding;
var preamble = encoding.GetPreamble();
ms.Write(preamble, 0, preamble.Length);
using var ms = ExportAsMemoryStream(encoding);
return ms.ToArray();
}

public MemoryStream ExportAsMemoryStream(Encoding encoding = null)
{
MemoryStream ms = new MemoryStream();

encoding = encoding ?? _defaultEncoding;
var preamble = encoding.GetPreamble();
ms.Write(preamble, 0, preamble.Length);

using (var sw = new StreamWriter(ms, encoding))
{
if (_includeColumnSeparatorDefinitionPreamble)
sw.Write("sep=" + _columnSeparator + "\r\n");
using (var sw = new StreamWriter(ms, encoding, 1024, leaveOpen: true))
{
if (_includeColumnSeparatorDefinitionPreamble)
sw.Write("sep=" + _columnSeparator + "\r\n");

foreach (var line in ExportToLines())
foreach (var line in ExportToLines())
{
int i = 0;
foreach (var value in line)
{
int i = 0;
foreach (var value in line)
{
sw.Write(value);

if (++i != _fields.Count)
sw.Write(_columnSeparator);
}
sw.Write("\r\n");
}
sw.Write(value);

sw.Flush(); //otherwise we're risking empty stream
if (++i != _fields.Count)
sw.Write(_columnSeparator);
}
sw.Write("\r\n");
}
return ms.ToArray();

sw.Flush(); //otherwise we're risking empty stream
}

ms.Position = 0;

return ms;
}
}
}
23 changes: 23 additions & 0 deletions UnitTests/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,29 @@ public void TestGeneric()

Assert.IsTrue(csv.Trim() == "sep=,\r\nId,Name\r\n123,Ffff\r\n321,ddd", csv);
}

[TestMethod]
public void WriteToFile()
{
var myExport = new CsvExport();
myExport.AddRow();
myExport["Region"] = "Los Angeles, USA";
myExport["Sales"] = 100000;
myExport["Date Opened"] = new DateTime(2003, 12, 31);

myExport.AddRow();
myExport["Region"] = "Canberra \"in\" Australia";
myExport["Sales"] = 50000;
myExport["Date Opened"] = new DateTime(2005, 1, 1, 9, 30, 0);

var filePath = Path.GetTempFileName();
myExport.ExportToFile(filePath);

Assert.IsTrue(File.Exists(filePath));
Assert.IsTrue(File.ReadAllText(filePath).Trim() == "sep=,\r\nRegion,Sales,Date Opened\r\n\"Los Angeles, USA\",100000,2003-12-31\r\n\"Canberra \"\"in\"\" Australia\",50000,2005-01-01 09:30:00", File.ReadAllText(filePath));

File.Delete(filePath);
}
}

public class MyClass
Expand Down

0 comments on commit f3a18a1

Please sign in to comment.