Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce LF line endings with CsvHelper

If I have some LF converted (using N++) CSV files, everytime I write data to them using JoshClose's CsvHelper the line endings are back to CRLF.

Since I'm having problems with CLRF ROWTERMINATORS in SQL Server, I whish to keep my line endings like the initital status of the file.

Couldn't find it in the culture settings, I compile my own version of the library.

How to proceed?

like image 998
user2863494 Avatar asked Feb 09 '15 21:02

user2863494


4 Answers

Missing or incorrect Newline characters when using CsvHelper is a common problem with a simple but poorly documented solution. The other answers to this SO question are correct but are missing one important detail.

Configuration allows you to choose from one of four available alternatives:

// Pick one of these alternatives
CsvWriter.Configuration.NewLine = NewLine.CR;   
CsvWriter.Configuration.NewLine = NewLine.LF;
CsvWriter.Configuration.NewLine = NewLine.CRLF;
CsvWriter.Configuration.NewLine = NewLine.Environment;

However, many people are tripped up by the fact that (by design) CsvWriter does not emit any newline character when you write the header using CsvWriter.WriteHeader() nor when you write a single record using CsvWriter.WriteRecord(). The reason is so that you can write additional header elements or additional record elements, as you might do when your header and row data comes from two or more classes rather than from a single class.

CsvWriter does emit the defined type of newline when you call CsvWriter.NextRecord(), and the author, JoshClose, states that you are supposed to call NextRecord() after you are done with the header and after you are done with each individual row added using WriteRecord. See GitHub Issues List 929

When you are writing multiple records using WriteRecords() CsvWriter automatically emits the defined type of newline at the end of each record.

In my opinion this ought to be much better documented, but there it is.

like image 96
Craig.Feied Avatar answered Oct 22 '22 23:10

Craig.Feied


Might be useful for somebody:

    public static void AppendToCsv(ShopDataModel shopRecord)
    {
        using (var writer = new StreamWriter(DestinationFile, true))
        {
            using (var csv = new CsvWriter(writer))
            {
                csv.WriteRecord(shopRecord);
                writer.Write("\n");
            }
        }
    }
like image 44
Trinitron Avatar answered Oct 23 '22 00:10

Trinitron


From what I can tell, the line terminator isn't controlled by CvsHelper. I've gotten it to work by adjusting the File writer I pass to CsvWriter.

TextWriter tw = File.CreateText(filepathname);
tw.NewLine = "\n";
CsvWriter csvw = new CsvWriter(tw);
csvw.WriteRecords(records);
csvw.Dispose();
like image 33
Brian Booth Avatar answered Oct 23 '22 00:10

Brian Booth


As of CsvHelper 13.0.0, line-endings are now configurable via the NewLine configuration property.

E.g.:

using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;

void Main()
{
    using (var writer = new StreamWriter(@"my-file.csv"))
    {
        using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csv.Configuration.HasHeaderRecord = false;
            csv.Configuration.NewLine = NewLine.LF; // <<####################

            var records = new List<Foo>
            {
                new Foo { Id = 1, Name = "one" },
                new Foo { Id = 2, Name = "two" },
            };

            csv.WriteRecords(records);
        }
    }
}

private class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}
like image 26
C. Augusto Proiete Avatar answered Oct 23 '22 01:10

C. Augusto Proiete