[JAVA] JAVA 파일 읽기, FileReader, Files.readAllLines

    자바 프로젝트를 수행 중, 로그성 데이터를 읽거나 프로퍼티등을 읽거나 라인별로 읽어야 프로젝트 수행이 원활 할 때가 있다. 기본적으로 많이 쓰이는 방식이 FileReader를 BufferedReader에 담아서, readLine 메소드를 활용하는 방법이다.




    FileReader에는 기본적으로 read 메소드(Byte별로 읽는 방법)는 있지만, readLine 메소드(라인별로 읽는 방법)는 없기에 로그성 데이터를 읽기에는 용이하지가 않다. Scanner 메소드는 대용량의 로그 데이터를 제대로 읽지 못하는 결과를 보여줬다. 처음에는 너무 빨라서 놀랐지만, length를 호출해보니, 적은 양의 파일을 읽고 있었다.



    대상로그



    로그치곤, 용량이 꽤 많다. 현재 운영중인 프로젝트의 로그를 대상으로 테스트 해보았다.



    1.  일반적인 FileReader를 BufferedReader에 담아서 사용하는 방법


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
         * 라인별 파일 읽는 메소드
         * 
         * @param filePath
         * @throws IOException
         */
        public int readFile(String filePath) {
            BufferedReader br = null;
            StringBuffer sb = new StringBuffer(); // 테스트용 변수
             try {
                br = new BufferedReader(new FileReader(filePath));
                String line = null;
                
                while ((line = br.readLine()) != null) {
                    //System.out.println(line);
                    sb.append(line);
                }
     
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
            } finally {
                try { 
                    if (br!=null) 
                        br.close(); 
                } catch (Exception e) {}
            }
             
             return sb.length();
        }
    cs


    정상적으로 파일을 가져오는지 궁금해서, length를 넣었다.


    71990128

    63473478

    end 2251ms


    71990128

    63473478

    end 2011ms


    71990128

    63473478

    end 1698ms


    용량은 얼추 비슷하고, 약 2000ms가 걸렸다(2초)



    이번에는 JDK7 부터 지원을 하는 방식이다. java.nio.file.* 패키지에서 정말 간단한 방식을 제공해준다.



    2. nio.file.* 패키지를 이용한 readAllLines 메소드 사용 방법


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
         * 라인별 파일 읽는 메소드
         * 
         * @param filePath
         * @throws IOException
         */
        public int readFileLines(String filePath) throws IOException {
            List<String> lines = Files.readAllLines(Paths.get(filePath), 
                    StandardCharsets.UTF_8);
            StringBuffer sb = new StringBuffer(); // 테스트용 변수
            for(String line: lines) {
                sb.append(line);
            }
            
            return sb.length();
        }
    cs


    기존의 방식과 속도 차이가 궁금했다. 결과는...


    71791432

    63296088

    end 2278ms


    71791432

    63296088

    end 2266ms


    71791432

    63296088

    end 2290ms


    약, 2200ms(2.2초)의 성능을 보여줬다.



    속도는 BufferedReader에 FileReader를 활용한 고전적인 방식이 승리를 거두었다.

    여기서 둘의 FileSize가 차이가 난다는 점을 확인할 필요가 있으며,


    사실 0.2초의 속도는 속도 차이가 있다라고 말하기가 힘이 든 속도이다.

    오히려, br.close() 를 할 필요가 없어서 소스가 훨씬 간결해지고, 가독성이 더 높아진 것은 사실이다.


    게다가, 전자는 while문을 써서 처음부터 읽어야 하지만, 후자의 방식은 List<String>으로 읽어서 이미 거의 완성된 형태를 보여준다. 한마디로 전자는 일반적으로 값을 다시 세팅해야 하지만 후자는 그럴 필요 없다는 의미이다. 


    문제는 아래 버전은 Java7(JDK7)버전이니, 솔루션을 만드는 업체라면 당연히 전자의 고전적인 방식을 채용해야 할 것이다. 아직도 사이트에서는 JDK6 버전을 많이 활용하고 있는 추세이다. 물론 본인 솔루션만 별도의 자바를 써서 호출하는 방식도 존재하지만, 사이트에 나가면 고객 담당자들은 추가 설치나 변경을 상당히 꺼려한다는 점을 참고해야 할 것이다.




    댓글

    Designed by JB FACTORY