내 응용 프로그램에 오프라인 보고서 용 약 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();
}
}
나는 BufferedWriter로 테스트를 실시했다. 평균적으로는 18-22 초가 걸렸다. 나는 이전 테스트 결과를 잃어 버렸기 때문에 테스트를 다시 시작합니다. 접근법 1, 나는 결과를 StringBuilder에 저장하고 반복의 끝에 BufferedWriter에 씁니다. (메모리 예외가있어서 접근법 2를 다시 작성했다.) 접근법 2, 행 결과에서 문자열을 형성하고 BufferedWriter에 기록하여 더 많은 디스크 쓰기를 작성하여 18 초가 소요됩니다. 접근법 3, iterating, BufferedWriter에 도달하면 (다시 설정) 결과를 ~ 20 초 동안 결과를 기록하는 동안 검사하는 최적의 수를가집니다. –
@VijayVeeraraghavan 버퍼링 된 작성자의 요점은 여러 번의 쓰기를 하나의 쓰기로 버퍼링하는 것입니다. 즉, BufferedWriter에 직접 쓰는 것은 나중에 BufferedWriter에 복사 할 StringBuilder에 대한 쓰기 수보다 빠릅니다. –
writeData()에 대한 주석을 작성하는 데 걸리는 시간도 알려주십시오. 따라서 우리는 모든 데이터를 가져 와서 얼마나 많은 시간을 필요로하는지 알 수 있습니다. – Ingo