2011-07-11 21 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的文件。沒有實現細節&邊界處理樂趣?;)

相關問題