使用CsvHelper强制使用LF行尾

15

如果我有一些经过N++转换的LF CSV文件,每次使用JoshClose的CsvHelper向它们写入数据时,行尾将回到CRLF。

由于我在SQL Server中遇到了CLRF ROWTERMINATORS问题,我希望保持我的行尾与文件的初始状态相同。

在文化设置中找不到它,我编译了自己版本的库。

如何继续?

4个回答

18

使用CsvHelper时,缺少或错误的Newline字符是一个常见问题,有一个简单但文档不够完善的解决方案。这个SO问题的其他答案都是正确的,但缺少一个重要细节。

配置允许您从四个可用的替代方案中选择:

// 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;

然而,许多人被这个事实绊倒了(按设计),当您使用CsvWriter.WriteHeader()写标题时,CsvWriter不会发出任何换行符,也不会在使用CsvWriter.WriteRecord()写入单个记录时发出任何换行符。原因是您可以写入其他标题元素或其他记录元素,就像当您的标题和行数据来自两个或更多类而不是单个类时所做的那样。
当您调用CsvWriter.NextRecord()时,CsvWriter会发出定义类型的换行符,并且作者JoshClose表示,您应该在完成标题并完成使用WriteRecord添加的每个单独行后调用NextRecord()请参见GitHub问题列表929 当您使用WriteRecords()写入多个记录时,CsvWriter会自动在每个记录末尾发出定义类型的换行符。
在我看来,这应该有更好的文档记录,但就是这样。

6
到了2020年,CsvHelper的文档仍然缺少重要信息和各种示例。我遇到了同样的问题:如果使用CsvWriter.WriteRecord(),标题和内容会在同一行。但是使用CsvWriter.NextRecord()就可以解决这个问题!感谢你,再也不用为此耗费脑细胞了 :) - J Pollack
1
更加令人困惑的是,CsvWriter.Flush() 表示“将行序列化到 TextWriter。”,这似乎表明 row 已经完成。如果该方法信息暗示您应该调用 NextRecord() 来写入 NewLine 字符,那将会很有帮助。 - JoeBrockhaus
截至2022年8月23日,它无法读取由Python csv库编写的csv文件。 - jjxtra

9
据我所知,行终止符并不受CvsHelper控制。 我通过调整传递给CsvWriter的文件写入器使其正常工作。
TextWriter tw = File.CreateText(filepathname);
tw.NewLine = "\n";
CsvWriter csvw = new CsvWriter(tw);
csvw.WriteRecords(records);
csvw.Dispose();

4

也许对某些人有用:

    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");
            }
        }
    }

4
截至 CsvHelper 13.0.0 版本,行尾现在可以通过NewLine配置属性进行配置

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; }
}

这在记录之间起作用,但你能在标题和第一条记录之间换行吗? - RickyTad
@RickyTad,我不确定我理解你的问题。上面的示例代码在写完标题后确实会插入一个新行:header\nrecord1\nrecord2等。 - C. Augusto Proiete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接