스트림은 byte만 사용할 수 있으므로, String 같은 문자는 직접 전달할 수 없다는 점이다.
개발자가 번거롭게 다음과 같은 변환 과정을 직접 호출
String writeString = "ABC";
// 문자 -> byte 변환 UTF-8 인코딩
byte[] writeBytes = writeString.getBytes(UTF_8);
byte[] bytes = fis.readAllBytes();
// byte -> String UTF-8 디코딩
String readString = new String(bytes, UTF_8);
이렇게 번거로운 변환 과정을 누군가 대신 처리해준다면?
OutputStream -> 전부 바이트 단위로 동작
Writer -> 문자라는 뜻
package io.text;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static io.text.TextConst.FILE_NAME;
import static java.nio.charset.StandardCharsets.UTF_8;
public class ReaderWriterMainV2 {
public static void main(String[] args) throws IOException {
String writeString = "ABC";
System.out.println("write String:" + writeString);
// 파일에 쓰기
FileOutputStream fos = new FileOutputStream(FILE_NAME);
OutputStreamWriter osw = new OutputStreamWriter(fos, UTF_8);
osw.write(writeString);
osw.close();
// 파일에서 읽기
FileInputStream fis = new FileInputStream(FILE_NAME);
InputStreamReader isr = new InputStreamReader(fis, UTF_8);
StringBuilder content = new StringBuilder();
int ch;
while ((ch = isr.read()) != -1) {
content.append((char) ch);
}
isr.close();
System.out.println("read String: " + content);
}
}

OutputStreamWriter는 문자를 입력 받고, 받은 문자를 인코딩해서 byte[]로 변환OutputStreamWriter는 변환한 byte[]을 전달할 OutputStream과 인코딩 문자 집합에 대한 정보가 필요 -> new OutputStreamWriter(fos, UTF_8) osw.write(writeString)을 보면 String 문자를 직접 전달하는 것을 확인 가능OutputStreamWriter가 문자 인코딩을 통해서 byte[]로 변환하고, 변환 결과를 FileOutputStream에 전달하는 것을 확인할 수 있다.
int ch = read()를 제공한다. (문자 하나인 char형으로 데이터를 받게되지만 실제 반환타입은 int형이므로 char 형으로 캐스팅 해한다.char형은 파일의 끝인 -1을 표현할 수 없으므로 int를 반환 FileInputStream에서 byte[]을 읽는다. InputStreamReader는 이렇게 많은 byte[]을 문 자인 char로 변경해서 반환. (문자 집합 필요)new InputStreamReader(fis, UTF_8)문자를 저장하는 건 없다.
컴퓨터는 오로지 바이트만 저장 가능 !
어디선가 반드시 한번은 문자를 바이트로 변환하거나
바이트로 문자를 변환해야 우리가 문자를 볼 수 있다.
그냥 문자를 파일에 저장 X
바이트 변환없이 문자를 직접 다룰 수 있다.
byte를 다루는 클래스

byte를 다루는 클래스는 OutputStream, InputStream의 자식.
byte 단위를 다룬다.OutputStream, InputStream이 붙어있다.
문자를 다루는 클래스는 Writer, Reader의 자식이다.
String, char 같은 문자를 다룬다.Writer, Reader가 붙어있다. Write, Reader 클래스의 자식들은 writer(String)이 가능하다.
OutputStreamWriter는 문자를 받아서 byte로 변경한 다음에 byte를 다루는 OutputStream으로 데이터를 전달한 것이다.
모든 파일이나 모든 외부의 데이터 전달은 바이트로 하는 것
package io.text;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import static io.text.TextConst.*;
import static java.nio.charset.StandardCharsets.*;
public class ReaderWriterMainV3 {
public static void main(String[] args) throws IOException {
String writeString = "ABC";
System.out.println("write String:" + writeString);
// 파일에 쓰기
FileWriter fw = new FileWriter(FILE_NAME, UTF_8);
fw.write(writeString);
fw.close();
// 파일에서 읽기
StringBuilder content = new StringBuilder();
FileReader fr = new FileReader(FILE_NAME, UTF_8);
int ch;
while ((ch = fr.read()) != -1){
content.append((char) ch);
}
fr.close();
System.out.println("read string = " + content);
}
}
new FileWriter(FILE_NAME, UTF-8)
FileWriter에 파일명과, 문자 집합을 전달.FileWriter는 내부에서 스스로 FileOutputStream을 하나 생성해서 사용public FileWriter(String fileName, Charset charset) throws IOException {
super(new FileOutputStream(fileName), charset);
}
fw.write(writeString)
FileWrite 내부에서는 인코딩 셋을 사용해서 문자를 byte로 변경하고, FileOutputStream을 사용해서 파일에 저장.FileOutputStream fos = new FileOutputStream(FILE_NAME);
OutputStreamWriter osw = new OutputStreamWriter(fos, UTF_8);
FileWriter fw = new FileWriter(FILE_NAME, UTF_8);
FileWrite는 FileOutputStream, OutputStreamWrite의 생성을 동시에 할 수 있게 편리하게 만들어주는 것이다. BufferedReader는 한 줄 단위로 문자를 읽는 기능도 추가로 제공.package io.text;
import java.io.*;
import static io.text.TextConst.FILE_NAME;
import static java.nio.charset.StandardCharsets.UTF_8;
public class ReaderWriterMainV4 {
private static final int BUFFER_SIZE = 8192;
public static void main(String[] args) throws IOException {
String writeString = "ABC\n가나다";
System.out.println("== Write String");
System.out.println(writeString);
// 파일에 쓰기
FileWriter fw = new FileWriter(FILE_NAME, UTF_8);
BufferedWriter bw = new BufferedWriter(fw, BUFFER_SIZE);
bw.write(writeString);
bw.close();
// 파일에서 읽기
StringBuilder content = new StringBuilder();
FileReader fr = new FileReader(FILE_NAME, UTF_8);
BufferedReader br = new BufferedReader(fr, BUFFER_SIZE);
String line;
while ((line = br.readLine()) != null) {
content.append(line).append("\n");
}
br.close();
System.out.println("==Read String ==");
System.out.println(content);
}
}
br.readLine()
String을 반환null을 반환-System.out에서 사용되는 스트림
PrintStream과 FileOutputStream을 조합하면 마치 콘솔에 출력하듯이 파일에 출력 가능 package io.text.streams;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamEtcMain {
public static void main(String[] args) throws FileNotFoundException {
FileOutputStream fos = new FileOutputStream("temp/print.txt");
PrintStream printStream = new PrintStream(fos);
printStream.println("hello java!");
printStream.println(10);
printStream.println(true);
printStream.printf("hello %s", "world");
printStream.close();
}
}
String, int, double, boolean 같은 데이터 형을 편리하게 다룰 수 있다.FileOutputStream을 조합하면 파일에 자바 데이터 형을 편리하게 저장할 수 있다.package io.text.streams;
import java.io.*;
public class DateStreamEtcMain {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("temp/data.dat");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeUTF("회원A");
dos.writeInt(20);
dos.writeDouble(10.5);
dos.writeBoolean(true);
dos.close();
FileInputStream fis = new FileInputStream("temp/data.dat");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readUTF());
System.out.println(dis.readInt());
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
dis.close();
}
}
| 종류 | 설명 | 예시 |
|---|---|---|
| 기본 스트림 | File, 메모리, 콘솔 등 직접 접근하는 스트림 | FileInputStream, FileOutputStream, FileReader, FileWriter, ByteArrayInputStream, ByteArrayOutputStream |
| 보조 스트림 | 기본 스트림을 도와주는 스트림 | BufferedInputStream, BufferedOutputStream, InputStreamReader, OutputStreamWriter, DataOutputStream, DataInputStream, PrintStream |
기본 스트림 - 단독으로 사용 가능
보조 스트림 - 단독으로 사용 불가, 반드시 대상 스트림 필요
강의자료 출처: 김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션