
자바에서 파일이나 네트워크와 같은 외부 장치로 데이터를 읽고 쓰는 과정은 스트림(stream) 을 통해 일관되게 처리할 수 있습니다. 이 글에서는 입력 스트림의 동작 원리와 버퍼를 활용하여 성능을 최적화하는 방법에 대해 살펴보겠습니다.
자바에서 read() 메소드를 사용할 때, 미리 생성된 byte[] 버퍼를 전달하여 한 번에 여러 바이트를 읽어올 수 있습니다.
현대 컴퓨터는 바이트 단위로 데이터를 주고받으며, 스트림을 사용하면 파일 I/O, 네트워크 통신 등 다양한 데이터 전송 방식을 동일한 방식으로 다룰 수 있습니다.
참고:
read()와write()메소드가 호출될 때마다 OS의 시스템 콜이 발생하는데, 시스템 콜은 상대적으로 무거운 작업입니다. HDD나 SDD와 같은 저장 장치에서도 한 바이트씩 처리하면 성능에 큰 영향을 주므로, 버퍼를 활용하여 여러 바이트를 한 번에 처리하는 것이 효율적입니다.
자바에서는 기본 스트림(예: FileOutputStream, FileInputStream) 외에도, 보조 스트림으로서 BufferedOutputStream과 BufferedInputStream을 제공하여 버퍼 기능을 쉽게 사용할 수 있습니다.
주의: 반드시 대상 스트림(예:
FileOutputStream)이 필요합니다.
read() 호출 시 버퍼에서 데이터를 반환하여 성능을 개선합니다.다음 예제는 BufferedInputStream과 BufferedOutputStream을 사용하여 파일을 읽고 쓰는 과정을 보여줍니다.
import java.io.*;
public class BufferedFileCopy {
public static void main(String[] args) {
// 원본 파일과 대상 파일 경로 설정
String inputFile = "input.txt";
String outputFile = "output.txt";
// 4KB 크기의 버퍼 사용 (파일 시스템의 기본 단위와 유사)
byte[] buffer = new byte[4096];
try (
// 기본 스트림에 보조 스트림(버퍼 기능)을 추가
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outputFile))
) {
int bytesRead;
// 버퍼에 데이터를 읽어오면서 파일 전체를 복사
while ((bytesRead = bis.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, bytesRead);
}
// 버퍼에 남아있는 데이터를 출력 스트림에 완전히 전달
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}