2009-05-19 7 views

답변

8

새 응답

(아래 원래의 대답을 정보 Junking에 대한 설명을 참조하십시오.)

static void CopyFiles(string dest, params string[] sources) 
{ 
    using (TextWriter writer = File.CreateText(dest)) 
    { 
     // Somewhat arbitrary limit, but it won't go on the large object heap 
     char[] buffer = new char[16 * 1024]; 
     foreach (string source in sources) 
     { 
      using (TextReader reader = File.OpenText(source)) 
      { 
       int charsRead; 
       while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0) 
       { 
        writer.Write(buffer, 0, charsRead); 
       } 
      } 
     } 
    } 
} 

이 새로운 대답은 제외하고, 매우 마틴의 접근 방식과 같다 :

  • 그것은으로 읽어 더 작은 버퍼; 16K는
  • 그것은 두 가지 이유 텍스트 데이터 대신 데이터를 읽고 (압축하지 않음) 거의 모든 상황에서 허용 될 것입니다, 그리고 대형 개체 힙에 결국하지 않습니다
      코드는 용이하게 입력 파일 리더가 생략 될 바이트 순서 마크를 포함하는 경우, 대신에 분산 된 바이트 순서 마크와 종료하는 다른
    • 한 인코딩으로 변환하도록 수정 될 수
    • 입력 파일 경계에서 출력 파일을 통해
  • ,

원래 대답은

마틴 Stettner 아래의 대답에 문제를 지적 - 첫 번째 파일은 줄 바꿈없이 끝나는 경우, 여전히 출력 파일에 줄 바꿈을 만듭니다. 또한 이전에 "\ r"또는 "\ n"인 경우에도 줄 바꿈을 "\ r \ n"으로 변환합니다. 마지막으로, 긴 라인에 대해 많은 양의 데이터를 사용하는 데 무의미하게 위험합니다. 같은

뭔가 :이 한 번에 메모리에 너무 많이 읽는 피하기 위해 라인으로 라인을 읽는

static void CopyFiles(string dest, params string[] sources) 
{ 
    using (TextWriter writer = File.CreateText(dest)) 
    { 
     foreach (string source in sources) 
     { 
      using (TextReader reader = File.OpenText(source)) 
      { 
       string line; 
       while ((line = reader.ReadLine()) != null) 
       { 
        writer.WriteLine(line); 
       } 
      } 
     } 
    } 
} 

참고. 당신이 (한 번에 여전히 하나) 메모리에 완전히 각각의 파일을 읽을 행복하면 당신은 그것을 간단하게 만들 수 :

static void CopyFiles(string dest, params string[] sources) 
{ 
    using (TextWriter writer = File.CreateText(dest)) 
    { 
     foreach (string source in sources) 
     { 
      string text = File.ReadAllText(source); 
      writer.Write(text); 
     } 
    } 
} 
+0

Skeet이 나를 다시 꺾습니다! – jrcs3

+0

그는 단지 키보드를 살펴본 후 빛의 속도로 답을 입력하기 시작했습니다.:) –

+0

Skeet은 안드로이드 여야합니다. 그는 아마도 인간 일 수 없다. +1 – ichiban

2

편집 : 존 소총은 지적

, 텍스트 파일은 일반적으로해야 이진 파일 과 다르게 처리됩니다.

난 그냥 당신이 정말 큰 파일을 (예 : 다른 입력 파일을 출력 파일에서 다른 인코딩 또는 여러 Byte Order Marks 것으로) 문제 인코딩하여 concernded하지 않을 경우 더 확대됨에 될 수 있기 때문에이 대답 남겨

:

public void CopyFiles(string destPath, string[] sourcePaths) { 
    byte[] buffer = new byte[10 * 1024 * 1024]; // Just allocate a buffer as big as you can afford 
    using (var destStream= = new FileStream(destPath, FileMode.Create) { 
    foreach (var sourcePath in sourcePaths) { 
     int read; 
     using (var sourceStream = FileStream.Create(sourcePath, FileMode.Open) { 
     while ((read = sourceStream.Read(buffer, 0, 10*1024*1024)) != 0) 
      destStream.Write(buffer, 0, read); 
     } 
    } 
    } 
} 
+0

차이가 있습니다 - 모든 텍스트 파일이 바이트 순서 표시로 시작하면 어떻게되는지 생각해보십시오. 당신은 당신의 산출물이 오직 하나만 갖고 싶어 할 것이다. –

+0

이 점을 지적 해 주셔서 감사합니다. 흥미롭게도 MSDN은 File.OpenText() (또는 StreamReader)가 바이트 순서 표시를 사용한다고 언급하지 않습니다. BOM은 모든 StreamReader 생성자 설명서에서도 언급되지 않았습니다. 또한 MSDN은 File.OpenText가 실제로 StreamReader와 동일한 검색 메커니즘을 사용하므로 (다른 모든 지원되는 인코딩과 완벽하게 호환 됨) UTF-8 파일과 호환됩니다. – MartinStettner

+0

"다른 지원되는 인코딩"으로 문제를 해결할 것입니다. - "자동 감지 된 인코딩"은 매우 다른 것입니다. :) –

관련 문제