ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C#] StreamReader : 대용량 텍스트 파일 읽기
    프로그래밍/C# 2020. 9. 22. 07:20

     

     StreamReader 생성자

    우선 StreamReader는 간편하게 파일을 읽어오고 싶을 때 사용하는 클래스입니다.

    아래와 같이 생성하셔서 사용하시면 됩니다. 또한, 한글을 사용하자 하실 때는 인코딩 UTF8을 설정해주세요.

     

    StreamReader sr = new StreamReader(FilePath, Encoding.UTF8);

     

     

     

     

     StreamReader 속성

     

     1. EndOfStream

     

    :  현재 스트림 위치가 스트림의 끝에 있으면 true이고, 없으면 false입니다. 보통 속성은 " () " 를 사용하지 않고 메서드는 " () " 를 사용합니다.

     

     

     StreamReader 주요 메서드

     

     1. Read()

     

    : 입력 스트림에서 다음 문자를 읽고 문자 위치를 한 문자씩 앞으로 이동합니다.

    매개변수 없이 Read() 를 사용하는 경우 개체로 표시되는 입력 스트림의 다음 문자를 반환하게 되고, 사용할 수 있는 문자가 더 이상 없는 경우에는 -1을 반환하게 됩니다.

     

                while(sr.EndOfStream == false)
                {
                    Console.WriteLine(sr.Read());
                }

     

     

    2.  Read( Char [], Int32, Int32 )

     

    : 현재 스트림에서 지정된 최대 문자를 지정된 인덱스부터 버퍼로 읽어 들입니다. 

    Read 함수에 인자를 설정할 경우 읽어드린 문자의 수를 반환하고 매개변수인 Buffer에 읽어드린 내용을 저장합니다.

     

    • Char [] : buffer 변수
    • int32 : buffer의 시작 인덱스
    • int32 : buffer에 한 번에 담을 문자의 크기
                int bufferSize = 4096;
                char[] buffer = new char[bufferSize];
    
                while (sr.EndOfStream == false)
                {
                    int CharCount = sr.Read(buffer, 0, bufferSize);
                    Console.WriteLine("글자수 : " + CharCount + ", 내용 : " + buffer);
                }

     

     

    3. ReadLine()

     

    : 현재 스트림에서 한 줄의 문자를 읽고 데이터를 문자열로 반환합니다.

    읽어드린 내용을 String으로 반환하기 때문에 즉시 출력이 가능합니다.

     

                while (sr.EndOfStream == false)
                {
                    
                    Console.WriteLine(sr.ReadLine());
                }

     

     

     

    4. ReadToEnd()

     

    : 가장 자주 사용하는 메서드로 현재 위치에서 마지막까지의 전체 내용을 String으로 반환해줍니다.

     

                string allOfContents = sr.ReadToEnd();
                Console.WriteLine(allOfContents);
    

     

     

     

     

     대용량 텍스트 파일 읽기

    이제 대용량 텍스트를 읽는 방법입니다. 보통 ReadToEnd() 메서드를 사용하면 1GB  정도의 내용도 한 번에 읽는 것이 가능합니다. 하지만 10Gb, 100GB 로 내용이 커지면 OutOfMemory라는 오류가 발생하게 됩니다. 

     

    결론만 말하자면 반복문을 사용하면서 읽어온 내용을 바로 쓰고 내용을 비워주는 작업이 필요합니다. 그러기 위해서는 StreamReader 와 StreamWriter 를 동시에 선언해서 사용해야 하는데, 코드를 보시면서 이해하시면 편할 것 같습니다. 

     

    참고 : StreamWriter 의 생성자에서 파일 경로에 지정한 파일이 없는 경우 텍스트 파일을 만들어 저장하게 됩니다.

     

     

            StreamWriter sw = new StreamWriter(textBoxSnpFilePath.Text + ".new", false);
            StreamReader sr = new StreamReader(textBoxSnpFilePath.Text, Encoding.UTF8);
    
            int bufferSize = 4096; // Basic Stream Size
            int remainBuffer = 0;
            char[] buffer = new char[bufferSize];
    
            while(sr.EndOfStream == false)
            {
                remainBuffer = sr.Read(buffer, 0, bufferSize);
    
                if (sr.EndOfStream) break;
                sw.Write(buffer);
            }
    
            // write reamin contents
            for(int i=0; i< remainBuffer; i++)
            {
                sw.Write(buffer[i]);
            }

     

    주의해야 할 부분은 Read() 메서드를 통해서 매번 4096개의 글자를 읽어드립니다. 하지만 마지막 부분은 정확히 나누어 떨어지는 글자 수가 아니라면 4096 보다 작은 문자 수를 읽어드리게 됩니다. 이때 직전에 읽어드렸던 내용들이 남아있게 되는데, 이 부분을 따로 for문을 돌려 처리해줄 필요가 있습니다. 언제나 질문은 댓글에 달아주시면 감사하겠습니다. ㅎㅎ

     

     

     

    댓글

Designed by Tistory.