I/O Stream (입출력 스트림)
- I/O : 데이터를 읽고 쓰는 작업
- 스트림 : 네트워크에서의 자료 흐름이 물의 흐름과 같다는 비유에서 유래
- 다양한 입출력 장치에 독립적으로 일관성 있는 입출력을 제공함
- 입출력 장치 ex) 파일 디스크, 키보드, 마우스, 네트워크, 메모리 등
- 한 방향으로만 움직임
입출력 스트림의 구분
# 대상 기준
1) 입력 스트림 (InputStream, Reader, ...)
2) 출력 스트림 (OutputStream, Writer, ...)
# 자료의 종류 기준
1) 바이트 단위 스트림 (InputStream, OutputStream, ...)
2) 문자 단위 스트림 (Reader, Writer, ...)
# 기능 기준
1) 기반 스트림
2) 보조 스트림 (Buffered~)
입력 스트림과 출력 스트림
//// 입력
// 바이트 스트림 (1 byte씩 키보드의 값을 입력받음)
int 변수 = System.in.read();
//// 출력
// 정수 값으로 그대로 출력
System.out.println(변수);
// 정수 값을 문자로 변환해서 출력 (인코딩)
System.out.println((char) 변수);
# 입력 스트림 (Java 프로그램 ← 입출력 자료)
- 대상으로부터 자료를 읽어 들이는 스트림
- 파일의 텍스트를 가져올 때, 더 이상 읽어올 텍스트가 없다면 -1을 반환함
- read() 메서드 : 한 글자씩 읽음 (반환 자료형 : int)
→ 보조 스트림의 readLine() 메서드를 이용하면 한 줄씩 읽을 수 있음 (Enter 전까지)
# 출력 스트림 (Java 프로그램 → 입출력 자료)
- 대상으로 자료를 출력하는 스트림
- Writer를 작성할 때에는 Stream이 열려 있으면 잠시 '버퍼'라는 공간에 담아 두었다가
flash()나 close()를 만나면 실제로 파일에 출력함
→ flush() 메서드 또는 close() 메서드를 사용하지 않으면 결과가 적용되지 않을 수 있음
- write 메서드 활용 방법
fw변수 = new FileWriter("파일명.확장자");
// 1. 문자 하나 (char)
fw.write('H');
// 2. 문자열
fw.write("문자열");
// 3. 배열 내 모든 문자들
fw.write(배열명);
// 4. 배열에서 시작인덱스a부터 n개만큼의 문자들
fw.write(배열명, 시작인덱스a, 길이n);
// FileOutputStream의 옵션
FileOutputStream fos변수 = new FileOutputStream("파일명.확장자", [true | false]);
// false (기본값) : 기존 파일이 있다면, 기존 내용을 초기화한 후 값을 출력함
// true : 기존 파일이 있다면, 기존 내용을 그대로 두고 값을 추가해서 출력함
바이트 스트림과 문자 스트림
# 바이트 스트림
- 동영상, 음악, 실행 파일 등의 자료를 읽을 때 사용함
- 한글을 사용하면 글자가 깨짐
- 예제 : https://young0105.tistory.com/104
# 문자 스트림
- 인코딩에 맞게 2 byte 이상으로 데이터를 처리함
→ 한글을 사용해도 글자가 깨지지 않음 (주로 사용됨)
기반 스트림과 보조 스트림
# 기반 스트림
- 대상에 직접 자료 읽고 쓰는 기능이 있는 스트림
# 보조 스트림
// 입력 + 바이트 단위
BufferedInputStream bis변수 = new BufferedInputStream(기반스트림);
// 입력 + 문자 단위
BufferedReader br변수 = new BufferedReader(기반스트림);
// BufferedReader의 메서드
br변수.readLine(); // 한 줄씩 읽음 ("\n" 이전까지)
----------------
// 출력 + 바이트 단위
BufferedOutputStream bos변수 = new BufferedOutputStream(기반스트림);
// 출력 + 문자 단위
BufferedWriter bw변수 = new BufferedWriter(기반스트림);
// BufferedWriter의 메서드
bw변수.newLine(); // 한 줄 띄움 (== "\n")
// 기반 스트림은 다시 사용할 필요가 없다면 익명 클래스로 만들어서 넣어도 됨
// ex) BufferedWriter bw 변수 = new BufferedWriter(new OutputStreamWriter(매개변수));
// 또는 따로 new 해서 변수명을 입력
- 직접 읽고 쓰는 기능은 없지만, 기반 스트림에 추가적인 기능을 더해주는 스트림
→ 상속과 유사하게 '기능의 확장'을 제공함
: 대신, 상속은 수직으로 확장, 보조 스트림은 수평으로 확장 (데코레이터 패턴)
- 항상 기반 스트림 or 또 다른 보조 스트림에 의존함 (생성자의 매개변수에 포함시킴)
데이터를 타입에 따라 다루는 보조 스트림
- DataInputStream
- DataOutputStream
public static void main(String[] args) {
// try-catch 생략 (실제 코드에선 써야 함)
FileOutputStream fos = null;
fos = new FileOutputStream("data.txt");
// 보조 기반 스트림 활용
DataOutputStream dos = new DataOutputStream(fos);
dos.writeChar('A');
dos.writeInt(10);
dos.writeFloat(3.14F);
dos.writeUTF("TEST UTF"); // 문자열 출력
dos.flush(); // 항상 기억하기
// 데이터 단위로 읽어보기
FileInputStream fis = null;
fis = new FileInputStream("data.txt");
// 보조 스트림 + data
DataInputStream dis = new DataInputStream(fis);
// 강제 형 변환할 필요가 없어짐
char a = dis.readChar();
int b = dis.readInt();
float c = dis.readFloat();
String d = dis.readUTF(); // 문자열 읽기
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
오토 클로즈
- close() 메서드를 호출할 필요 없이, 자동으로 리소스를 닫아줌
try (
// () 안에는 스트림 준비
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
) {
// {} 안에는 수행시킬 코드
String input = reader.readLine();
} catch (Exception e) {
e.printStackTrace();
}
'Java > Base' 카테고리의 다른 글
[Java] 소켓 양방향 통신 구현 (0) | 2023.03.04 |
---|---|
[Java] 소켓 통신 (0) | 2023.03.03 |
[Java] 입출력 스트림 - 예제 모음 (0) | 2023.03.03 |
[Java] Map - 전화번호부 프로그램 구현 (0) | 2023.02.22 |
[Java] 컬렉션 프레임워크 (List, Set, Map) (0) | 2023.02.22 |