Java 파일 복사(버퍼 크기 변경)
Java에서 java.io.InputStream,,,java.io.OutputStream 에서
입출력 스트림을 이용한 카피 처리를 실시하는 샘플 프로그램을 소개합니다.
스트림을 이용한 카피 처리에서는, 읽기 버퍼 사이즈를 크게 하는 것으로, 큰 파일에서도 비교적 고속으로 카피를 실시할 수 있습니다.
샘플 프로그램에서는 데이터의 읽어들여 버퍼 사이즈를 인수로 지정 가능하게 하고 있습니다.
지정한 read buffer area는 JavaVM의 heap내에 확보되기 때문에, 너무 크게 해도 효율이 나빠집니다. 따라서 파일을 복사할 때 효율적인 데이터 읽기 버퍼 크기를 동시에 확인합니다.
샘플 프로그램
/**
* 입력 스트림에서 출력 스트림에 데이터를 씁니다.
* 또한, 복사 처리 종료 후, 입력·출력 스트림을 닫습니다.
* @param in 입력 스트림
* @param os 출력 스트림
* @param bufferSize 데이터 읽기 버퍼 크기(KB)입니다.
* @throws IOException 어떠한 입출력 처리 예외가 발생했을 경우
*/
public static void copyStream(InputStream in, OutputStream os,
int bufferSize) throws IOException {
int len = -1;
byte[] b = new byte[bufferSize * 1024];
try {
while ((len = in.read(b, 0, b.length)) != -1) {
os.write(b, 0, len);
}
os.flush();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
실행
샘플 프로그램의 파일 카피를 실시하기 위해서, C드라이브 바로 아래에 100MB의 파일 「100M.txt」를 준비했습니다. 샘플 프로그램에서는 C:\100M.txt 버퍼 크기 1000KB 단위로 데이터를 읽습니다. C:\a.txt 에 복사합니다.
또한, 샘플의 실행은 이하의 환경에서 실시했습니다.
OS : WindowsXP
CPU : Athlon 1.46GHz
메모리 : 1GB
JRE : 1.6.4
◆실행예
/** * 예제 실행 * @param args */ public static void main(String[] args) { try { copyStream("C:\\100M.txt", "C:\\a.txt",1000); } catch (IOException e) { e.printStackTrace(); } }
버퍼 크기 변경
파일을 복사 할 때 효율적인 데이터 읽기 버퍼 크기를 확인하기 위해 copyStream의 세 번째 인수
1KB, 100KB, 1000KB, 10000KB 단위로 같은 복사 처리를 실시한 결과를 이하에 정리하고 있습니다.
위의 결과만으로 결정할 수는 없지만 데이터 읽기 버퍼 크기를 1000KB 단위로 지정하면
복사 처리 중의 힙 사용량, 처리 시간에 있어서 효율이 좋다고 하는 결과가 나왔습니다.
또한, 파일 사이즈를 크게 한 경우(1GB 정도)에서도 같은 결과가 얻어졌습니다.
반대로 사이즈가 작은 파일(1MB 이하 정도)을 카피하는 경우는, 버퍼 사이즈를 크게 해도 낭비가 되므로 100KB 정도로 지정하는 것이 좋을까 생각합니다.
FileChannel을 사용하여 더 빨리
java.io.InputStream,,,java.io.OutputStream
에서의 복사 처리는 입출력 스트림을 이해하는데 중요하지만,
J2SE1.4에서 도입 된 New I / O java.nio.channels.FileChannel#transferTo
메소드를 이용하는 것으로, 보다 효율적으로 파일 카피를 실시할 수 있습니다.
다음은 FileChannel을 사용하여 쉽고 빠르게 파일 복사를 수행하는 방법을 보여줍니다.
⇒ Java 파일 복사 (간단 · 고속)