首页 > 解决方案 > 有没有办法忽略或全局替换 CSVHelper 中的 NUL 字符?

问题描述

几年来我们一直在使用 CSVHelper 来读取文件,它非常棒。最近,我们从试图上传他们的文件的客户那里收到了几个错误——他们发现他们的文件中有 NUL(即 ASCII 零)字符。

例如,假设我们在输入文件中有以下内容 - 其中 NUL 实际上是 ASCII 0...

这个,那个,NUL,TheOther

CSVHelper 很好地读取了这一行 - 并将 NUL 值转换为 .NET 空值(即“\0”)。如果可能,我们希望改变这种行为,并让 CSVHelper 将任何 NUL 实例替换为 string.Empty。

我们已经考虑过一次读取整个文件并自己替换所有 NUL 字符,但如果有一种优雅的方式来执行此操作,则宁愿使用 CSVHelper 执行此操作。我可以更改我们所有的类映射并覆盖框中的所有类型转换器来执行此操作,但如果有更通用的解决方案,我宁愿使用它。

我查看了 CsvConfiguration.InjectionCharacters 属性和 SanitizeForInjection 可能会解决问题,但这看起来只是在字段的前面添加了一个转义字符。

任何建议都非常感谢,在此先感谢!

标签: csvhelper

解决方案


听起来你想用 CsvHelper 读取文件,用 string.Empty 替换 NUL 值,然后再次写回文件?如果是这样,我相信它可以使用自定义字符串转换器将记录作为动态列表读取以替换值,然后将它们再次写回文件。

public class Program
{
    public static void Main(string[] args)
    {
        using (MemoryStream stream = new MemoryStream())
        using (StreamWriter writer = new StreamWriter(stream))
        using (StreamReader reader = new StreamReader(stream))
        using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            writer.WriteLine("Property1,Property2,Property3,Property4");
            writer.WriteLine("This,That,\0,TheOther");
            writer.Flush();
            stream.Position = 0;

            csv.Configuration.TypeConverterCache.AddConverter<string>(new NulStringConverter());

            var records = csv.GetRecords<dynamic>().ToList();       

            using(var csvWriter = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
            {
                csvWriter.WriteRecords(records);
            }
        }

        Console.ReadKey();
    }
}

public class NulStringConverter : StringConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (text == "\0")
        {
            text = string.Empty;
        }

        return base.ConvertFromString(text, row, memberMapData);
    }
}

推荐阅读