删除标题时将相同的CSV添加到一起

时间:2011-07-11 16:52:57

标签: c# csv header append

我想要添加6个具有相同布局和标题的CSV。

我已经能够通过将6个csv中的每一个加载到它们自己的单独数据表中并删除每个数据表的第一行来实现这一点。最后,我使用ImportRow方法将它们附加在一起。

DataTable table1 = csvToDataTable(@"C:\Program Files\Normalization\Scan1.csv");
DataTable table2 = csvToDataTable(@"C:\Program Files\Normalization\Scan2.csv");
DataTable table3 = csvToDataTable(@"C:\Program Files\Normalization\Scan3.csv");
DataTable table4 = csvToDataTable(@"C:\Program Files\Normalization\Scan4.csv");
DataTable table5 = csvToDataTable(@"C:\Program Files\Normalization\Scan5.csv");
DataTable table6 = csvToDataTable(@"C:\Program Files\Normalization\Scan6.csv");

        foreach (DataRow dr in table2.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table3.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table4.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table5.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table6.Rows)
        {
            table1.ImportRow(dr);
        }

        CreateCSVFile(table1, @"C:\Program Files\Normalization\RackMap.csv");

我觉得这很笨重而且不是很容易扩展,但是当我尝试在CSV级别附加时,我无法处理标题。有什么建议吗?

TIA

3 个答案:

答案 0 :(得分:7)

获取与掩码*.csv

匹配的所有文件的DirectoryInfo

创建一个for循环来迭代结果。

导入每个文件时删除第一行。

修改

如果您只想组合文件,而不是导入数据表,则可以将它们视为文本文件。连接它们,每次都删除标题行。这是一个例子:

string myPath = @"K:\csv";

DirectoryInfo csvDirectory = new DirectoryInfo(myPath);
FileInfo[] csvFiles = csvDirectory.GetFiles("*.csv");
StringBuilder sb = new StringBuilder();
foreach (FileInfo csvFile in csvFiles)
    using (StreamReader sr = new StreamReader(csvFile.OpenRead()))
    {
        sr.ReadLine(); // Discard header line
        while (!sr.EndOfStream)
            sb.AppendLine(sr.ReadLine());
    }
File.AppendAllText(Path.Combine(myPath, "output.csv"), sb.ToString());

答案 1 :(得分:2)

正如JYelton建议的那样,你肯定想要动态查找你文件夹中的所有* .csv文件,并迭代它们(而不是硬编码6个文件名)。从那时起,您可能会考虑这样的方法:

  1. 为“目标”文件创建可写文件流。
  2. 对于每个.CSV文件,打开一个可读的文件流。
  3. 通过读取包含第一个CRLF并将数据丢弃来丢弃每个文件的标题行。
  4. 将所有剩余数据读入您的可写流。
  5. 对每个CSV文件重复#2-4。
  6. 关闭可写流以保存已完成的文件。
  7. 此方法将容纳任意数量的CSV文件,并且可能比使用DataTables更具性能效率。

    注意:为了简洁起见清晰度,我遗漏了一些你需要做的边缘案例处理。就像如何处理一个空的csv文件,或者一个包含标题行而没有其他内容的文件,或者一个在最后一行之后没有尾随CRLF的文件。不是实施细节&边缘处理有趣吗? ;)

答案 2 :(得分:1)

如果你不想重复相同的行,那么你可以创建哈希码列表并在循环中查找列表是否包含行的哈希码。

    List<int> rowHashCodes = new List<int>();
    foreach (DataRow dr in table2.Rows)
    {
        int hash = dr.GetHashCode();
        if (rowHashCodes.Contains(hash))
        {
            // We already have this row
        }
        else
        {
            table1.ImportRow(dr);
            rowHashCodes.Add(hash);
        }
    }

可能这对于性能观点来说不是理想的方式,但我希望这可以解决您的问题。