자바의 I/O(Input/Output) Stream은 마치 우리 집으로 연결된 **'수도관'**과 같습니다.
📘 자바 I/O 스트림: "데이터가 흐르는 길"
1. 스트림(Stream)이란?
- 자바에서 데이터는 스트림이라는 통로를 통해 흐릅니다.
- 한쪽 방향으로만 흐르는 단방향 통로이기 때문에, 데이터를 읽어올 때와 보낼 때 각각의 빨대가 필요합니다.
- 입력(Input): 데이터가 프로그램 안으로 들어오는 것 (읽기)
- 출력(Output): 데이터가 프로그램 밖으로 나가는 것 (쓰기)
📦 I/O의 4대 핵심 클래스
데이터를 어떤 단위로 옮기느냐에 따라 크게 바이트(Byte) 기반과 문자(Character) 기반으로 나뉩니다.
1. InputStream (바이트 입력의 조상)
- 바이트 단위로 데이터를 읽어오는 최상위 추상 클래스입니다.
- 그림, 영상, 음악 파일처럼 0과 1로 이루어진 이진 데이터를 읽을 때 주로 사용합니다.
- 수도꼭지에서 물 한 방울(1 Byte)씩 받아내는 과정이라고 생각하면 쉽습니다.
- 주요 메서드: read()
2. OutputStream (바이트 출력의 조상)
- 바이트 단위로 데이터를 내보내는 최상위 추상 클래스입니다.
- 프로그램에서 가공한 이미지나 실행 파일 등을 밖으로 저장할 때 사용합니다.
- 데이터를 한 방울씩 밖으로 뿜어내는 역할을 합니다.
- 주요 메서드: write(), flush(), close()
3. Reader (문자 입력의 조상)
- **문자 단위(2 Byte)**로 데이터를 읽어오는 최상위 추상 클래스입니다.
- 텍스트 파일(.txt)처럼 우리가 읽을 수 있는 글자를 다룰 때 사용합니다.
- 자바는 유니코드를 사용하기 때문에, 1바이트씩 읽으면 한글 같은 문자가 깨질 수 있는데 이를 방지해 줍니다.
- 한자 한자 정성껏 읽어주는 통역사 같은 존재입니다.
4. Writer (문자 출력의 조상)
- 문자 단위로 데이터를 내보내는 최상위 추상 클래스입니다.
- 텍스트 형식의 문서나 로그를 파일로 저장할 때 사용합니다.
- 문자를 깨뜨리지 않고 안전하게 종이에 써내려가는 펜과 같습니다.
👨🏫 실무 꿀팁: "어떤 걸 골라 써야 할까요?"
- 바이트 스트림(InputStream/OutputStream): 이미지, 동영상, 실행 파일 등 텍스트가 아닌 모든 데이터.
- 문자 스트림(Reader/Writer): 메모장 파일, HTML 코드, 설정 값 등 사람이 읽을 수 있는 모든 텍스트 데이터.
⚠️ 주의사항 (Gotcha!)
스트림은 사용이 끝나면 반드시 close() 메서드를 호출해 닫아주어야 합니다. 수도꼭지를 틀어놓고 나가면 물이 낭비되듯, 스트림을 닫지 않으면 시스템 자원(메모리 등)이 줄줄 새어나가 프로그램이 멈출 수도 있습니다. 최근에는 try-with-resources 문법을 사용해 자동으로 닫히게 만드는 것이 표준입니다.
오늘의 요약
- InputStream/OutputStream: 0과 1의 바이트 세계 (이미지, 영상용).
- Reader/Writer: 글자로 된 문자 세계 (텍스트 파일용).
- 모든 스트림은 단방향이며, 다 쓴 뒤에는 반드시 닫아야(close) 한다.
📘 자바 I/O 실습: "글자 쓰고 읽기"
자바에서 가장 많이 쓰이는 문자 기반(Reader/Writer) 스트림으로 메모장 파일을 만들고 읽어보는 예제입니다.
1. Writer로 파일에 글자 쓰기 (데이터 내보내기)
먼저 FileWriter를 이용해 "Hello Java"라는 문장을 파일에 적어보겠습니다.
Java
import java.io.FileWriter;
import java.io.Writer;
import java.io.IOException;
public class WriteExample {
public static void main(String[] args) {
// 1. Writer 준비 (파일 이름: test.txt)
try (Writer writer = new FileWriter("test.txt")) {
String str = "Hello Java! 자바 공부 화이팅!";
// 2. 데이터 보내기
writer.write(str);
System.out.println("파일 쓰기 완료!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. Reader로 파일 글자 읽기 (데이터 가져오기)
이제 방금 만든 test.txt 파일을 FileReader로 읽어서 화면에 출력해 보겠습니다.
Java
import java.io.FileReader;
import java.io.Reader;
import java.io.IOException;
public class ReadExample {
public static void main(String[] args) {
// 1. Reader 준비
try (Reader reader = new FileReader("test.txt")) {
int data;
// 2. 한 글자씩 읽어서 출력하기
// 더 이상 읽을 글자가 없으면 -1을 반환합니다.
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
System.out.println("\n파일 읽기 완료!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
📦 바이트 스트림 vs 문자 스트림 한눈에 보기
| 구분 | 바이트 스트림 (Binary) | 문자 스트림 (Text) |
| 단위 | 1 byte (숫자 0~255) | 2 byte (유니코드 문자) |
| 조상 클래스 | InputStream / OutputStream | Reader / Writer |
| 사용 예시 | 이미지, 음악, 동영상 파일 | 텍스트 문서, HTML, 로그 |
| 특징 | 데이터 원본 그대로를 옮김 | 문자가 깨지지 않게 변환해줌 |
👨🏫 쉽게 이해하는 핵심 포인트
- try-with-resources 문법: 예제 코드의 try ( ... ) 부분입니다.
- 작업이 끝나면 자바가 알아서 수도꼭지(close)를 잠가주기 때문에 아주 편리하고 안전합니다.
- -1의 의미: read() 메서드가 -1을 던지면 "이제 더 이상 흐를 데이터가 없어요(끝이에요)"라는 뜻입니다.
- InputStream/OutputStream도 사용법은 똑같습니다!
- 단지 다루는 대상이 '문자'가 아니라 '바이트(데이터 조각)'일 뿐입니다.
오늘의 요약
- 글자를 다룰 땐 Reader / Writer를 쓰면 한글이 안 깨진다.
- 데이터를 보낼 땐 write(), 가져올 땐 read() 메서드를 쓴다.
- try ( ... ) 괄호 안에 스트림을 선언하면 자동으로 닫혀서 안전하다.
이제 직접 파일을 만들고 읽는 코드를 작성하실 수 있게 되었습니다!

'JAVA 80%' 카테고리의 다른 글
| I/0 API (0) | 2025.11.06 |
|---|---|
| Decorator Stream (0) | 2025.11.06 |
| LIFO/FIFO collection - Stack - Queue (0) | 2025.11.06 |
| Collection framework (0) | 2025.11.05 |
| Thread control (0) | 2025.11.05 |