CSV 列中的新行导致问题

New line within CSV column causing issue

我有一个包含数百万行的大型 csv 文件。样本 csv 行是

CODE,COMPANY NAME, DATE, ACTION
A,My Name , LLC,2018-01-28,BUY
B,Your Name , LLC,2018-01-25,SELL
C,
All Name , LLC,2018-01-21,SELL
D,World Name , LLC,2018-01-20,BUY

C行有换行,但实际上这是同一条记录。我想从 cell\field\column.

中的 csv 行中删除换行符

我厌倦了 \r\nEnvirnment.NewLine 和许多其他事情,但无法让它发挥作用。

这是我的代码..

 private DataTable CSToDataTable(string csvfile)
    {
        Int64 row = 0;
        try
        {

            string CSVFilePathName = csvfile; //@"C:\test.csv";
            string[] Lines = File.ReadAllLines(CSVFilePathName.Replace(Environment.NewLine, ""));
            string[] Fields;
            Fields = Lines[0].Split(new char[] { ',' });
            int Cols = Fields.GetLength(0);
            DataTable dt = new DataTable();
            //1st row must be column names; force lower case to ensure matching later on.
            for (int i = 0; i < Cols; i++)
                dt.Columns.Add(Fields[i].ToLower(), typeof(string));
            DataRow Row;
            for (row = 1; row < Lines.GetLength(0); row++)
            {
                Fields = Lines[row].Split(new char[] { ',' });
                Row = dt.NewRow();
                //Console.WriteLine(row);
                for (int f = 0; f < Cols; f++)
                {
                    Row[f] = Fields[f];
                }
                dt.Rows.Add(Row);
                if (row == 190063)
                {
                }
            }
            return dt;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

如何删除换行符并正确读取该行?我不想根据业务需求跳过这些行。

您还没有明确在文件中出现不需要的新行的可能条件是什么。因此,假设 CSV 文件中的 'proper' 行不以逗号结尾,如果以逗号结尾,则意味着它不是格式正确的行,您可以这样做:

static void Main(string[] args)
{
    string path = @"CSVFile.csv";

    List<CSVData> data = new List<CSVData>();
    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        using (StreamReader sr = new StreamReader(fs))
        {
            sr.ReadLine();  // Header
            while (!sr.EndOfStream)
            {
                var line = sr.ReadLine();
                while (line.EndsWith(","))
                {
                    line += sr.ReadLine();
                }
                var items = line.Split(new string[] { "," }, StringSplitOptions.None);
                data.Add(new CSVData() { CODE = items[0], NAME = items[1], COMPANY = items[2], DATE = items[3], ACTION = items[4] });
            }
        }
    }

    Console.ReadLine();
}

public class CSVData
{
    public string CODE { get; set; }
    public string NAME { get; set; }
    public string COMPANY { get; set; }
    public string DATE { get; set; }
    public string ACTION { get; set; }
}

显然这里有很多错误处理要做(例如,当创建一个新的 CSVData 对象时确保你的 items 包含你想要的所有数据),但我认为这是你需要的开始。

您的 CSV 文件格式无效。为了成功解析和加载它们,您必须对它们进行清理。几个问题

  1. COMPANY NAME 列中包含字段分隔符。修复它们 周围引号。
  2. CSV 值中的新行 - 这可以通过将相邻行合并为一个来解决。

使用 Cinchoo ETL,您可以按如下方式清理和加载大文件

string csv = @"CODE,COMPANY NAME, DATE, ACTION
A,My Name , LLC,2018-01-28,BUY
B,Your Name , LLC,2018-01-25,SELL
C,
All Name , LLC,2018-01-21,SELL
D,World Name , LLC,2018-01-20,BUY";

string bufferLine = null;
var reader = ChoCSVReader.LoadText(csv)
    .WithFirstLineHeader()
    .Setup(s => s.BeforeRecordLoad += (o, e) =>
    {
        string line = (string)e.Source;
        string[] tokens = line.Split(",");

        if (tokens.Length == 5)
        {
            //Fix the second and third value with quotes
            e.Source = @"{0},""{1},{2}"",{3}, {4}".FormatString(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]);
        }
        else
        {
            //Fix the breaking lines, assume that some csv lines broken into max 2 lines
            if (bufferLine == null)
            {
                bufferLine = line;
                e.Skip = true;
            }
            else
            {
                line = bufferLine + line;
                tokens = line.Split(",");
                e.Source = @"{0},""{1},{2}"",{3}, {4}".FormatString(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]);
                line = null;
            }
        }
    });

foreach (var rec in reader)
    Console.WriteLine(rec.Dump());

//Careful to load millions rows into DataTable
//var dt = reader.AsDataTable();

希望对您有所帮助。