Есть ли способ игнорировать или глобально заменять NUL-символы в CSVHelper? - PullRequest
0 голосов
/ 07 февраля 2020

Мы использовали CSVHelper в течение нескольких лет для чтения файлов, и это великолепно. Недавно мы получили пару ошибок от наших клиентов, которые пытались загрузить свои файлы - и выяснилось, что в файле есть NUL (то есть ноль ASCII).

Например, скажем, у нас было следующее во входном файле - где NUL на самом деле ASCII 0 ...

This, That, NUL, TheOther

CSVHelper прекрасно читает эту строку - и преобразует значение NUL в a. NET ноль (то есть '\ 0'). Мы хотели бы изменить это поведение, если это возможно, и сделать так, чтобы CSVHelper связывал любой экземпляр NUL с помощью string.Empty.

Мы рассмотрели чтение всего файла один раз и замену всех символов NUL сами, но лучше сделать это с CSVHelper, если есть элегантный способ сделать это. Я мог бы изменить все наши карты классов и переопределить все преобразователи типов в блоке, чтобы сделать это, но если есть решение более общего назначения, я бы лучше использовал это.

Я посмотрел на CsvConfiguration Свойство .InjectionCharacters и SanitizeForInjection могут сработать, но похоже, что это просто добавляет escape-символ в начале поля.

Любые предложения с благодарностью приняты, заранее спасибо!

1 Ответ

1 голос
/ 07 февраля 2020

Звучит так, как будто вы хотите прочитать файл с помощью CsvHelper, заменить значения NUL на string.Empty, а затем снова записать файл? Если так, то я считаю, что это будет работать для чтения записей в виде динамического списка c с использованием специального преобразователя строк для замены значений и последующей записи их обратно в файл.

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