우주개발

Java, 버퍼를 통한 파일 입출력은 왜 효율적인가? 본문

Java

Java, 버퍼를 통한 파일 입출력은 왜 효율적인가?

우주개발 2023. 10. 11. 11:17

버퍼(Buffer)

일시적으로 데이터를 저장하는 중간 저장소이다. 컴퓨터 메모리(RAM)에서 할당되고, 입출력(I/O) 작업, 변환, 전송등 다양한 연산에서 데이터를 임시로 저장하고 처리하는 데 사용된다.

버퍼의 장점

I/O 최적화

하드 드라이브, 네트워크, 키보드 등 I/O 장치와의 통신은 비용이 큰데. 작은 크기의 데이터를 여러번 읽고 쓰는 것은 비효율적이기 때문에 버퍼를 사용해 큰 데이터를 한 번에 읽거나 쓸 수 있게 한다.

데이터 스트림 처리

스트리밍 데이터, 가령 영상이나 오디오 스트리밍을 처리할 때 버퍼는 데이터의 일관된 흐름을 유지하는 데 도움을 줄 수 있다. 네트워크 지연을 극복하기 위해 데이터를 버퍼에 저장하고 꺼내쓸 수 있도록 하는 것이다.

데이터 변환 및 조작

데이터를 변환하거나 조작할 때 버퍼는 중간 결과 값을 저장하는 데 사용된다.

속도 차이 극복

CPU는 빠르게 데이터를 처리할 수 있지만, 출력장치가 데이터를 느리게 받아들일 때 버퍼는 두 장치간 속도 차이를 해소하는데 도움을 준다.

순서 보장

데이터 패킷이 순차적이지 않게 도착할 때, 버퍼는 데이터를 올바른 순서로 재 배열하여 처리하는 데 사용될 수 있음

버퍼 사용시 고려할점

오버플로
버퍼의 크기는 한정적이기 때문에, 버퍼가 가득 찬 상태에서 데이터가 더 들어오게 되면 오버플로가 발생하게 된다.

버퍼를 사용한 파일 입출력(I/O)

`바이트 기반 버퍼링 출력 스트림`

  • BufferedInputStream
  • BufferedOutputStream

`문자 기반 버퍼링 입출력 스트림`

  • BufferedReader
  • BufferedWriter

BufferedReader의 경우 줄씩 텍스트를 읽는 readLine() 메소드를 제공한다.

🤔 BufferedReader와 FileReader를 왜 같이 사용할까?

BufferedReader reader = new BufferedReader(new FileReader("sample.txt"))
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

여기서 고민이 있었는데, 왜 BufferedReader 인스턴스 생성시 FileReader를 생성해야하는지.
FileReader의 경우 FileReader 클래스 메소드에서 read() 의 입력을 반복해야하기 때문에 데이터를 여러번 읽어야 한다는 단점이 존재했다.
그래서 BufferedReader를 통해서 해당 파일을 통째로 읽어버린 다음에 read() 메소드를 사용해 한 줄씩 읽어들이는게 훨씬 더 효과적이라고 한다. I/O 횟수가 크게 감소하게 되기 때문이다.

✔️ BufferedWrite

BufferedWriter writer = new BufferedWriter(new FileWriter("sample.txt"))) 
writer.write("This is an example of buffered file writing.");
writer.newLine();
writer.write("Buffering improves I/O efficiency.");

BufferedWrite 클래스의 경우도 마찬가지이다. 똑같이 FileWrite 클래스를 통해서 write를 했을 때 작은 단위의 I/O가 증가하게 되기 때문에 BufferedWrite 클래스를 통해서 이를 줄일 수 있기 때문이다.