C # StreamReader ReadLine разрыва строк на внутренних разрывах строк в ячейках - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть строка данных в CSV, где некоторые ячейки могут содержать разрывы строк

enter image description here

Я загружаю этот файл, используяAsp: FileUpload и пытается прочитать каждую строку с помощью StreamReader:

var file = btnFileUpload.PostedFile;
using (StreamReader sr = new StreamReader(file.InputStream))
{
    string currentLine;
    var line = 1;
    // currentLine will be null when the StreamReader reaches the end of file
    while ((currentLine = sr.ReadLine()) != null)
    {
          ....do stuff...
    }
}

Однако при отладке я обнаружил, что sr.ReadLine() разбивает строки на разрывы строк в ячейках, например в категорииклетка.Например, когда я читаю строку 2 (первая строка данных после заголовка), значение равно:

"/Home/Blog/2018/november/power,English : English,Erica Stockwell-Alpert,/Home/Blog/Categories/Accounts Payable Automation;"

, а затем следующий sr.ReadLine ():

"/Home/Blog/Categories/Financial Services;"

, а затем

"/Home/Blog/Categories/Robotic Process Automoation,<p>[the rest of the line]"

Как можно предотвратить прерывание sr.ReadLine () символов новой строки в ячейках?Или, если я не могу, как еще я могу прочитать файл построчно?

Примечание: я не могу использовать csv reader ClassMap и csvReader.GetRecords, потому что инструмент, над которым я работаю, должен уметь обрабатыватьлюбые другие поля в заголовке, это не связано с одним конкретным классом.Поэтому мне нужно прочитать файл построчно.

1 Ответ

0 голосов
/ 29 ноября 2018

Вы путаете строк с записями .Вы говорите, что хотите читать свой файл построчно, но на самом деле вы хотите читать его по записи.Поскольку ваши данные могут иметь разрывы строк в середине записи, то использование ReadLine не даст вам того, что вы хотите, потому что этот метод не знает, где находится конец записи.Он только знает, как найти следующий разрыв строки.

Вам понадобится использовать соответствующий CSV-ридер, чтобы решить эту проблему.Но, не волнуйтесь, есть читатели CSV, которые не требуют, чтобы вы отображали данные в фиксированный класс.Я много раз использовал Lumenworks CSV Reader .Он бесплатный (с открытым исходным кодом, лицензия MIT), поддерживает многострочные поля в записи и прост в использовании.

Вот пример того, как вы будете использовать его для обработки файла запись-запись:

using (StreamReader sr = new StreamReader(file.InputStream))
using (CsvReader csv = new CsvReader(sr, hasHeaders: true))
{
    csv.SupportsMultiline = true;

    // read the first record of the file as column headers and put them into an array
    string[] headers = csv.GetFieldHeaders();

    // read each data record one by one - this returns false when there is no more data
    while (csv.ReadNextRecord())
    {
        // 0-based index of the current CSV record (excluding the headers) if you need it
        var recordNumber = csv.CurrentRecordIndex;

        // loop over the columns in the row and process them
        for (int i = 0; i < csv.FieldCount; i++)
        {
            string fieldName = headers[i];
            string fieldValue = csv[i];      // may contain line breaks

            // ...do stuff...
        }
    }
}

Рабочая демонстрация: https://dotnetfiddle.net/ZYSA7r

...