2011-08-02 49 views
0

我正在編寫一個將數據庫表寫入CSV文件的應用程序。由於許多表都有超過一百萬條記錄,因此我給了用戶一個將大型表寫入每行25,000行文件的選項。我希望用戶在SaveFileDialog中指定初始文件名,然後爲寫入的每個新文件附加「-part1」,「-part2」等。如何編程寫入多個文件直到寫入所有數據?下面列出了我必須編寫25,000行文件的當前代碼。以編程方式編寫多個CSV文件

public void ExportPartition(SaveFileDialog saveFile, DataTable table) 
    { 
     TextWriter writer = new StreamWriter(saveFile.FileName, true, System.Text.Encoding.ASCII, 1048576); 

     for (int i = 0; i <= 25000; i++) 
     { 
      for (int j = 0; j < table.Columns.Count; j++) 
      { 
       writer.Write(table.Rows[i][j].ToString() + ","); 
      } 
      writer.Write("\r\n"); 
     } 
     writer.Flush(); 
     DisposeObjects(saveFile, writer); 
    } 
+0

您也可能要考慮處理有逗號在它們領域已經所以導入操作不會失敗。 –

+0

是否應該在每行結尾都有一個逗號? – alun

+0

我只是寫了這個很快,我沒有注意到在行末的逗號。感謝那。在這些字段中沒有包含逗號的數據,但爲了可重用性,我應該解決這個問題。 – Andrew

回答

0
bool ExportPartition(string fileName, DataTable table, int batchSize, int batchNum) 
    { 
     string fn = string.Format("{0}-{1}{2}",          
            Path.GetFileNameWithoutExtension(fileName), 
            batchNum, 
            Path.GetExtension(fileName)); 

     fn = Path.Combine(Path.GetDirectoryName(fileName), fn); 

     using (TextWriter writer = new StreamWriter(fn)) 
     { 
      int start = batchNum * batchSize; 
      int end = start + batchSize; 

      for (int i = start; i < end; i++) 
      { 
       if (i >= table.Rows.Count) 
        break; 

       for (int j = 0; j < table.Columns.Count; j++) 
       { 
        writer.Write(table.Rows[i][j] + ","); 
       } 
       writer.Write("\r\n"); 
      } 

      return table.Rows.Count <= end; 
     } 
    } 

用法:

void WriteFiles(DataTable table, String fileName, int batchSize) 
    { 
     int batchNum = 0;   
     bool done = false; 
     while (!done) 
     { 
      done = ExportPartition(fileName, table, batchSize, batchNum++); 
     } 
    } 

    void Main() 
    { 
     DataTable dt = GetData(); 
     string fileName = GetFileNameWithSaveDialog(); 
     int batchSize = 25000; 
     WriteFiles(dt, fileName, batchSize); 
    } 
+0

我已經實現了這個,但是它在TextWriter構造函數上拋出了IO異常。這是錯誤消息: 進程無法訪問文件'C:\ Users \ afannin1 \ Equipment \ HBSSensorDataClient \ HBSDataClient \ HBSDataClient \ bin \ Debug \ Partitions - 0..csv',因爲它正在被另一個進程使用。 – Andrew

+0

你在文件名(..csv)中看到兩個點嗎?擴展名可能包括點,我會更新格式字符串。正在使用的文件感覺很奇怪,你是否已經在另一個應用程序(例如文本編輯器或以前運行的程序實例)中打開它? –

+0

我能解決這個問題和擴展的問題。應用程序現在正在編寫這些文件,但是實現中使用的while循環沒有終止。 – Andrew

0

另一種解決方案:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DataTable dt = new DataTable(); 
     dt.Columns.Add("Col1"); 
     dt.Columns.Add("Col2"); 
     for (int i = 0; i < 103; ++i) 
     { 
      var r = dt.NewRow(); 
      r[0] = Guid.NewGuid().ToString(); 
      r[1] = i.ToString(); 
      dt.Rows.Add(r); 
     } 
     WriteCsvFile(dt, 25, @"C:\temp\test.txt"); 
    } 

    public static string[] ToStringArray(DataRow row) 
    { 
     var arr = new string[row.Table.Columns.Count]; 
     for (int j = 0; j < arr.Length; j++) 
     { 
      arr[j] = row[j].ToString(); 
      if((arr[j]??"").Contains(",")) 
       throw new Exception("This will end badly..."); 
     } 
     return arr; 
    } 

    public static void WriteCsvFile(DataTable table, int maxCount, string fileName) 
    { 
     if (table.Rows.Count <= maxCount) 
      WriteCsvFile(table, maxCount, fileName, 0); 
     else 
      for (int i = 0; i < (table.Rows.Count/maxCount + 1); ++i) 
      { 
       var partFileName = Path.Combine(Path.GetDirectoryName(fileName), string.Format("{0}-part{1}{2}", Path.GetFileNameWithoutExtension(fileName), i+1, Path.GetExtension(fileName))); 
       WriteCsvFile(table, maxCount, partFileName, i * maxCount); 
      } 
    } 

    public static void WriteCsvFile(DataTable table, int maxCount, string fileName, int startIndex) 
    { 
     using(var fs = File.Create(fileName)) 
     using(var w = new StreamWriter(fs, Encoding.ASCII)) 
     { 
      for (int i = startIndex; i < Math.Min(table.Rows.Count, startIndex + maxCount); i++) 
       w.WriteLine(String.Join(",", ToStringArray(table.Rows[i]))); 
      w.Flush(); 
     } 
    } 
}