2011-07-11 35 views
2

我想追加6个具有相同布局和标题的CSV。在删除标题时将相同的CSV添加到一起

我已经能够通过将6个csvs中的每一个加载到它们自己的单独数据表中并删除每个数据表的第一行来完成此操作。最后我使用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

回答

7

获取匹配的面具*.csv

创建一个for循环迭代结果的所有文件的一个DirectoryInfo。

导入每个文件时,拖放第一行。

编辑:

如果你只是想结合文件,而不是导入到数据表中,你可以把它们当作文本文件。连接它们,每次放下标题行。这里有一个例子:

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()); 
+0

我已经有一个方法,当将每个csvs导入到数据表时删除第一行。我正在寻找一种解决方案,在CSV级别将这些csvs合并在一起(同时删除标头),然后将最终的csv加载到数据表中。如果我不需要,我宁愿不使用创建6个数据表的内存。 – kmc5117

+0

@kmc我已经添加了一个例子,测试了三个12MB的csv文件。 – JYelton

+0

好主意分解到文本文件级别。我正在推翻它。这10行代替了我写过的100行。非常感谢你。 – kmc5117

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

可能是这不是理想的性能方式,但我希望这可以解决您的问题。

2

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

  1. 为您的“目标”文件创建一个可写的文件流。
  2. 对于每个.CSV文件,在其上打开一个可读的文件流。
  3. 通过读取包含第一个CRLF并丢弃数据来丢弃每个文件的标题行。
  4. 将所有剩余的数据读入您的可写入流。
  5. 对每个CSV文件重复#2-4。
  6. 关闭您的可写入流以保存完成的文件。

此方法将适用于任意数量的CSV文件,并且可能比使用DataTable更高的性能效率。

注意:为了简洁起见,我省略了一些你需要做的边缘案例处理。就像如何处理一个空的csv文件,或者是一个包含一个标题行而没有其他东西的东西,或者是一个在最后一行之后没有后续CRLF的文件。没有实现细节&边界处理乐趣?;)