2013-07-25 2 views
5

파일 크기가 수백만 줄에 달하기 때문에 파일에서 손상된 행을 확인하고 제거해야합니다.대용량 텍스트 파일 읽기 및 수정 3-3GB

나는 뻔뻔하게 File.ReadAllLines을 시도했지만 작동하지 않았습니다. 그런 다음 원본 파일에서 아래의 내용을 읽고 새 파일에 쓰는 것처럼 줄을 흘려 보려고했습니다. 그것이 일을하는 동안, 그것은 몇 시간 (5+)에 그렇게한다. 나는 유일한 옵션처럼 들리는 버퍼를 사용하는 방법에 대해 읽었지만 어떻게 그런 식으로 라인 무결성을 유지할 것인가?

솔루션 : StreamWriter가 외부로 이동했습니다. split 대신 count가 사용됩니다.

using (FileStream inputStream = File.OpenRead((localFileToProcess + ".txt"))) 
{ 
    using (StreamReader inputReader = new StreamReader(inputStream, System.Text.Encoding.GetEncoding(1254))) 
    { 
     using(StreamWriter writer=new StreamWriter(localFileToProcess,true,System.Text.Encoding.GetEncoding(1254))) 
     { 
      while (!inputReader.EndOfStream) 
      { 
      if ((tempLineValue = inputReader.ReadLine()).Count(c => c == ';') == 4) 
      { 
       writer.WriteLine(tempLineValue); 
      } 
      else 
       incrementCounter(); 
      } 
     } 
    } 
} 
+3

Split (';')은 배열을 할당하고 각 줄마다 메모리에 5 개의 문자열을 만듭니다. 이것은 가비지 컬렉터에 대한 작업을 추가합니다. 어쩌면 선에 4 개의 세미콜론이 있는지 확인해야할까요? 또한 각 반복은 StreamWriter를 생성/삭제합니다. 처음에 하나를 만들어 운영 종료시 폐기하는 것이 더 좋지 않습니까? – Artemix

+0

좋은 지적. 나는 변화를 만들거야. – mechanicum

+0

문자열 작성기로 배치를 읽고 프로세스를 작성한 다음 한 번에 작성하는 방법은 무엇입니까? – bhs

답변

1

원본 코드에서 가장 느린 부분은 StreamWriter를 작성/삭제하는 것입니다. 각 Dispose에서 StreamWriter는 디스크에 기록되지 않은 모든 데이터를 플러시하고 파일 핸들을 닫아야합니다. 열린 OS에서는 보안 사용 권한을 확인해야하며 현재 잠금은 다른 많은 작업을 수행해야합니다.

하나의 StreamWriter 만 사용하기 시작하면 내부 쓰기 버퍼가 데이터를 큰 청크로 디스크에 쓰는 작업을 시작했습니다. 쓰기 닫기/열기 파일을 건너 뛰는 것과 함께 많은 시간을 절약 할 수 있습니다. 디스크 I/O는 대개 애플리케이션에서 가장 느린 부분입니다.

스플릿 (';')도 속도에 영향을 줄 수 있지만 그다지 중요하지 않다고 생각합니다. 어쨌든, 문자열은 immutable이고 메모리에 많은 쓰레기를 생성 할 수 있기 때문에 C#에서는 문자열 연산을 신중하게 수행해야합니다. 따라서 4 세미콜론을 검사 할 수 있다면 배열을 할당하고 각 줄마다 메모리에 5 개의 문자열을 만드는 Split (';')을 호출하는 것보다 항상 낫습니다. 많은 문자열 연산이 불변 문자열을 사용하여 수행 될 때 디스크 입출력 없이도 응용 프로그램 성능에 심각한 타격을 줄 수 있습니다.

귀하의 경우 StringBuilder를 사용하여 - 나는 StreamWriter에 이미 내장 버퍼링 기능이 있기 때문에 많은 도움이된다고 생각하지 않습니다.