2013-12-10 2 views
1

내 응용 프로그램에 오프라인 보고서 용 약 1200 (+/- 200) mb, csv 파일을 씁니다. (스레드가이 작업을 수행합니다.) 데이터 수는 약 5 천만 개가 될 수 있으므로 쿼리는 50K 행마다 실행됩니다. 쿼리 루프는 지정된 조건에 대해 빈 fetch가 실행될 때까지 실행됩니다. 파일에 데이터를 쓰려면 Java 스트림을 사용하는 대신 nio를 사용하십시오. 50000 라인의 거대한 문자열을 쓰기에는 ~ 12 초가 걸렸습니다. BufferedWriter로 시도한 동일한 코드는 약 18-22 초가 걸렸습니다. nio 접근법 코드는 아래와 같습니다. 거대한 파일을 작성하는 데 nio를 사용하는 것이 쉬운 방법인지 알고 싶습니다. 내가 간과 한 것, 놓친 것? 다른 방법으로 최적화 및 코드 개선을 환영합니다.NIO로 큰 텍스트 파일 작성

private static void writeData(FileChannel channel, String data) { 
    ByteBuffer buffer = null; 
    try { 
     buffer = Charset.forName("UTF-8").encode(
       CharBuffer.wrap(data.toCharArray())); 
     channel.write(buffer); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
private String writeReport() { 
    try { 
     FileOutputStream out = new FileOutputStream(pathToFile, true); 
     FileChannel channel = out.getChannel(); 
     // db query 
     while(iterate resultset) { 
      // get row result 
      writeData(channel, data); 
     } 
    } catch(Exception e){ 
     //log 
    } finally { 
     channel.close(); 
     out .close(); 
    } 
} 

//pseudo code with bufferedwriter 
private String writeReport(Resultset rs, String file) { 
    try { 
     BufferedWriter writer = new BufferedWriter(new FileWriter(file), 1024 * 10); 
     int headerCount = 0; 
     while(rs.next()) { 
      String col1 = rs.getString(1); 
      String col2 = rs.getString(2); 
      String col3 = rs.getString(3); 
      String col4 = rs.getString(4); 
      String col5 = rs.getString(5); 
      String colN= rs.getString(n); //nth column 
      if(headerCount==0) { 
       writeHeader(writer); 
       headerCount++; 
      } 
      if(col1.equals(condition1)) { 
       writer.append(col1).append(","); 
      } 
      ...... 
      if(colN.equals(conditionN)) { 
       writer.append(colN).append(",").append(newLine()); 
      } 
     } 
    } catch(Exception e){ 
     //log 
    } finally { 
     writer.close(); 
    } 
} 

답변

2

그게 내가 코드를보고 싶은 느린 있었다면 아마 BufferedWriter. 함께있을 것입니다 파일을 작성하는 가장 빠른 방법. NIO는 여기에 놀랄만 한 어떤 것을 제공 할 것으로 기대해서는 안되며 게시 한 코드는 더 많은 실제 쓰기를 수행하므로 BufferedWriter,보다 빠르지 않습니다.

+0

나는 BufferedWriter로 테스트를 실시했다. 평균적으로는 18-22 초가 걸렸다. 나는 이전 테스트 결과를 잃어 버렸기 때문에 테스트를 다시 시작합니다. 접근법 1, 나는 결과를 StringBuilder에 저장하고 반복의 끝에 BufferedWriter에 씁니다. (메모리 예외가있어서 접근법 2를 다시 작성했다.) 접근법 2, 행 결과에서 문자열을 형성하고 BufferedWriter에 기록하여 더 많은 디스크 쓰기를 작성하여 18 초가 소요됩니다. 접근법 3, iterating, BufferedWriter에 도달하면 (다시 설정) 결과를 ~ 20 초 동안 결과를 기록하는 동안 검사하는 최적의 수를가집니다. –

+2

@VijayVeeraraghavan 버퍼링 된 작성자의 요점은 여러 번의 쓰기를 하나의 쓰기로 버퍼링하는 것입니다. 즉, BufferedWriter에 직접 쓰는 것은 나중에 BufferedWriter에 복사 할 StringBuilder에 대한 쓰기 수보다 빠릅니다. –

+0

writeData()에 대한 주석을 작성하는 데 걸리는 시간도 알려주십시오. 따라서 우리는 모든 데이터를 가져 와서 얼마나 많은 시간을 필요로하는지 알 수 있습니다. – Ingo