2011-08-02 9 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(); 
     } 
    } 
} 
관련 문제