C#StreamReader ReadLine在单元格内部换行处的换行

时间:2018-11-28 21:07:58

标签: c# csv newline readline streamreader

我在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()在单元格(例如Category单元格)中的换行符处断行。例如,当我读取第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读取器ClassMap和csvReader.GetRecords,因为我正在使用的工具需要能够处理标头中的任何不同字段,它与一个特定的类无关。因此,我需要逐行阅读文件。

1 个答案:

答案 0 :(得分:1)

您正在将记录混淆。您说要逐行读取文件,但是您真正想要做的就是逐记录读取文件。由于您的数据可能在记录的中间有换行符,因此使用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