💡 바이트 기반에 입력 스트림을 활용해서 파일에 있는 데이터를 읽어 보자.
package io.file.ch01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MyFileInputStream {
public static void main(String[] args) {
// 외부에 있는 파일 데이터를 읽으려면 input 이 필요
FileInputStream in = null;
try {
in = new FileInputStream("a.txt");
// 1단계
// int readData = in.read();
// 2단계
// System.out.println((char)in.read());
// System.out.println((char)in.read());
// System.out.println((char)in.read());
// 3단계
// 읽을 데이터가 더이상 없다면 -1 을 반환한다.
int readData;
while ((readData = in.read()) != -1) {
System.out.print((char)readData);
}
// 4단계
// FileInputStream(기반 스트림) 대상에 접근해서 한 바이트 씩 읽어 들이는 기능을 가진다.
// 1byte -> 127 -128 : a -> 97, A -> 65, 한글은 -> 대 -> ?
// 한글은 최소 2byte라 글자가 깨짐
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
기반 스트림 (Base Stream)이란?
기반 스트림은 데이터 소스와 직접 연결되는 스트림으로, 실제 데이터 읽기나 쓰기 작업을 수행한다. 이 스트림들은 데이터의 실제 입력 소스 (파일, 메모리, 네트워크 연결 등)에 직접 연결되어 데이터를 바이트 단위로 읽거나 쓰는 기본적인 기능을 제공한다.
- 바이트 기반 스트림 : FileInputStream , FileOutputStream , SocketInputStream , SocketOutputStream 등이 있으며, 이들은 바이트 데이터를 처리한다.
- 문자 기분 스트림 : FileReader , FileWriter 등이 있으며, 이들은 문자 데이터를 처리한다.
보조 스트림 (Fileter Stream) 이란?
보조 스트림은 기반 스트림 또는 다른 보조 스트림에 연결되어 사용된다. 이 스트림들은 데이터를 변환하거나, 추가 기능을 제공하거나, 성능을 향상시키는 역할을 한다. 보조 스트림은 자체적으로 데이터 소스에 연결되지 않으며, 항상 다른 스트림을 필요로 한다.
- 버퍼링 : BufferedInputStream , BufferedOutputStream , BufferedReader , BufferedWriter 는 내부적으로 버퍼를 사용하여 데이터를 모아서 한 번에 처리한다. 보조 스트림은 자체적으로 데이터 소스에 연결되지 않으며, 항상 다른 스트림을 필요로 한다.
- 데이터 변환 : DataInputStream , DataOutputStream 은 기본 데이터 타입 (int, float, long 등) 을 쉽게 읽고 쓸 수 있게 해준다.
- 객체 직렬화 : ObjectInputStream , ObjectOutputStream 은 객체를 바이트 스트림으로 직렬화하거나 바이트 스트림에서 객체를 복원하는 기능을 제공한다.
- 문자 인코딩 : InputStreamReader , OutputStreamWriter 는 바이트 스트림을 문자 스트림으로 변환하거나 반대의 작업을 할 때 사용되며, 인코등 변환을 처리한다.
💡 기반 스트림과 보조스트림에 활용
FileInputStream fis = new FileInputStream("input.txt"); // 기반 스트림
BufferedInputStream bis = new BufferedInputStream(fis); // 보조 스트림
데코레이터로 장식 / 데코레이터 패턴
기반 스트림 + 보조 스트림을 사용해 보자
package io.file.ch01;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class MyBufferedInputStream {
public static void main(String[] args) {
// 보조 스트림의 사용 -> 기반 스트림이 필요하다.
FileInputStream fin = null;
BufferedInputStream bfin = null;
try {
// 기반 스트림
fin = new FileInputStream("a.txt");
// 보조 스트림 (기반 스트림)
bfin = new BufferedInputStream(fin);
int data;
while( (data = bfin.read()) != -1 ) {
System.out.print((char)data);
}
} catch (Exception e) {
// 리소스 자원 정리 -> 반대로 -> 열었던 자원에서 순서를 반대로 닫아 주면 된다.
if(bfin != null) {
try {
bfin.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(fin != null) {
try {
fin.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}// end of main
}// end of class
a.txt 파일 ↓
Hello World.
By Tenco.
한글 작성
작동 방식
- 첫번째 read( ) 호출 : BufferedInputStream 은 내부 버퍼를 사용하여 데이터 소스로부터 많은 양의 데이터를 미리 읽는다. (예를 들어 버퍼 크기가 8192바이트일 경우 최대 8192바이트를 읽는다)
- 데이터 반환 : 사용자가 read( ) 를 호출할 때 마다 BufferedInputStream 은 버퍼에서 한 바이트씩 데이터를 반환한다.
- 버퍼 재충전 : 버퍼에 있는 모든 데이터가 읽혔다면, 다음 read( ) 호출 때 다시 데이터 소스에서 버퍼 크기만큼 데이터를 읽어 버퍼를 재충전한다.
BufferedInputStream.read()를 호출하여 한 바이트씩 데이터를 읽는다. 이 때, 실제 파일 접근은 버퍼가 비워질 때만 발생하므로 파일 접근 횟수가 줄어들어 성능이 향상된다.
728x90
'Java' 카테고리의 다른 글
파일 Copy ( 바이트기반 입/출력 ) (0) | 2024.05.16 |
---|---|
파일 출력 스트림 ( 바이트 기반 ) (0) | 2024.05.16 |
표준 입출력 (0) | 2024.05.14 |
자바 I/O 개론 (0) | 2024.05.14 |
Inner class ( 중첩 클래스 ) (0) | 2024.05.14 |