K-DigitalTraining 강의/1. Java

[5주차] 83. 바이트스트림(FileInputStream / FileOutputStream) 에 버퍼추가 => BufferedInputStream/BufferedOutputStream - 파일에서 한 글자씩 읽고 저장

이대곤 2022. 6. 7. 12:34

* 버퍼란?

  스트림으로부터의 입/출력 속도를 향상 시키기 위한 메모리(RAM)의 임시 저장소이다. 

  한 바이트씩 파일을 입출력하는 것보다 버퍼(바이트배열)를 이용해서 한 번에 여러 바이트를 입출력하는 것이 빠르므로
  대부분의 입출력 작업에 사용된다. 버퍼의 크기를 정해주지 않으면 기본적으로 8192byte이다.

 

* FileInputStream / FileOutputStream 을 BufferedInputStream/BufferedOutputStream 으로 감싸서 사용함으로써
  얻는 효과

  BufferedOutputStream을 사용하면 버퍼에 버퍼의 사이즈만큼 n개가 차고 n+1번째꺼가 밀고 들어오면
  그제서야 한번에 대량으로 Output장치로의 실제 전송(저장)이 수행된다.(BufferedInputStream은 살짝 다른데 생략)

  버퍼는 메모리에 존재하여 데이터를 가지고 있다가 디스크에 나중에 접근하여 저장. 이런 방식이다.
 
  반면, FileOutputStream 은 close()를 만나거나 flush()를 해줘야만 실제 전송(저장)이 수행된다.

 

* 1차 스트림을 이용해 2차 스트림을 만든 경우

  2차 스트림만 close 해주면 된다.
  close 할 때 내보내겠다.

 

* 스트림.close()의 숨겨진 기능

 close 해주면 버퍼에 있지만 아직 파일로 내보내지지 않은걸 내보내게 한다.
  이와 비슷한 효과를 갖는 것으로 스트림.flush() 메소드가 있다.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Ex11_06_Buffer {
	public static void main(String[] args) {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		FileOutputStream fos;
		FileInputStream fis;
		
		try {
			fos = new FileOutputStream("data.txt"); // data.txt 와 자바 파일이 형성된 관계를 '1차 스트림' 이라고 함
			bos = new BufferedOutputStream(fos, 5); // 1차 스트림을 이용해 크기가 5인 2차 스트림을 만드는 것
			
			// 스트림을 close 해주는게 없을 시 10까지 하라고 했지만 5까지만 파일에 저장된 이유는 버퍼에 6개 까지 밀고 들어와야 파일로 전송되기 때문.		
			// 만약 10까지 파일에 정상적으로 저장하고 싶다면 for문을 11까지 돌게 해줘야 한다.
			for(int i = 1; i <=10 ; i++) {
				bos.write(i+48);
				// 'A' : 65, 'a' : 97, '0' : 48, '1' : 49
			}// 실제 여기서는 파일 저장이 1번만 일어남
			
			// 6 7 8 9 10(아스키 코드가 넘어가서 ':' 이 들어갈 것임)
			//bos.close();
			//bos.flush(); // 버퍼에 있는걸 강제적으로 내보내는 것 (변기에 있는 찌꺼기를 내보내는 단어적인 의미)
			
			fis = new FileInputStream("data.txt");
			bis = new BufferedInputStream(fis, 5); // 버퍼에 5개가 쌓이면 파일에 가져가라 
			int j;
			
			while((j = bis.read()) != -1) {
				System.out.println((char)j + " ");
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 1차 스트림을 이용해 2차 스트림을 만든 경우 2차만 close 해주면 된다.
				bis.close();
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} 
	}
}