java.io
패키지데이터 흐름 ⇒ 단방향
ex. 물 위→아래처럼)
파이프 개념
사용자의 입력 데이터를 읽어드리는 통로
어떤 파일에 등록된 데이터/메시지를 입력 스트림으로 읽어들임
⇒ 입력데이터(키보드)와 파일 2가지를 동시에 읽어들이려면 입력스트림 2개 필요
데이터 출력은 불가(반대방향임)
입력스트림
→ Java App→ 출력스트림
→ 모니터Object
File
InputStream
- FileInputStream
- FilterInputStream → BufferedInputStream
OutputStream
- FileOutputStream
- FilterOutputStream → BufferedOutputStream, PrintStream
Reader
- BufferedReader
- InputStreamReader → FileReader
Writer
- BufferedWriter
- OutputStreamWriter → FileWriter
- PrintWriter
입력 스트림
대상으로부터 자료를 읽어 들이는 스트림
출력 스트림
대상으로 자료를 출력하는 스트림
종류 | 예시 |
---|---|
입력 스트림 | FileInputStream, FileReader, BufferedInputStream, BufferedReader 등 |
출력 스트림 | FileOutputStream, FileWriter, BufferedOutputStream, BufferedWriter 등 |
바이트 단위 스트림
동영상, 음악 파일, 실행 파일등의 자료를 읽고 쓸 때 사용
문자 단위 스트림
바이트 단위로 자료를 처리하면 문자는 깨짐, 인코딩에 맞게 2바이트 이상으로 처리하도록 구현된 스트림
종류 | 예시 |
---|---|
바이트 스트림 | FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream 등 |
문자 스트림 | FileReader, FileWriter, BufferedReader, BufferedWriter 등 |
기반 스트림
대상에 직접 자료를 읽고 쓰는 기능의 스트림
보조 스트림
직접 읽고 쓰는 기능은 없이 추가적인 기능을 더해주는 스트림
보조 스트림은 직접 읽고 쓰는 기능은 없으므로
항상 기반 스트림이나 또 다른 보조 스트림을 생성자의 매개 변수로 포함함
종류 | 예시 |
---|---|
기반 스트림 | FileInputStream, FileOutputStream, FileReader, FileWriter 등 |
보조 스트림 | InputStreamReader, OutputStreamWriter, BufferedInputStream, BufferedOutputStream 등 |
→ InputStreamReader : 입력용 바이트스트림을 문자로!
표준 입출력 장치
System
클래스의 멤버변수(in
, out
) 사용
outputStream의 타입은 PrintStream
ex. PrintStream output = System.out;
inputStream의 타입은 InputStream
ex. InputStream input = System.in;
public class System {
public static PrintStream out;
public static InputStream in;
public static PrintStream err;
}
System.out.println("출력 메세지");
int d = System.in.read() // 한 바이트 읽기
System.err.println("에러 메세지");
System.in
,System.out
한글 깨짐 현상
System.out.println("알파벳 하나를 쓰고 [Enter]를 누르세요");
int i;
try {
while((i = System.in.read()) != '\n') { // read() 반환값은 integer
// System.out.println(i);
System.out.print((char)i);
}
} catch (IOException e) {
e.printStackTrace();
}
출력결과
알파벳 하나를 쓰고 [Enter]를 누르세요
안녕하세요
??@$%*
InputStreamReader
System.out.println("알파벳 하나를 쓰고 [Enter]를 누르세요");
int i;
try {
InputStreamReader irs = new InputStreamReader(System.in); // 보조스트림으로 byte를 문자로
while((i = irs.read()) != '\n') {
System.out.print((char)i);
}
} catch (IOException e) {
e.printStackTrace();
}
출력결과
알파벳 하나를 쓰고 [Enter]를 누르세요
안녕하세요
안녕하세요
바이트 단위 입력 스트림, 최상위 추상 클래스
스트림 클래스 | 설명 |
---|---|
FileInputStream | 파일에서 바이트 단위로 자료를 읽습니다. |
ByteArrayInputStream | byte 배열 메모리에서 바이트 단위로 자료를 읽습니다. |
FilterInputStream | 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스 |
메서드 | 설명 |
---|---|
int read() | 입력 스트림으로부터 한 바이트의 자료를 읽습니다. 읽은 자료의 바이트 수를 반환합니다. |
int read(byte b[]) | 입력 스트림으로 부터 b[] 크기의 자료를 b[]에 읽습니다. 읽은 자료의 바이트 수를 반환합니다. |
int read(byte b[], int off, int len) | 입력 스트림으로 부터 b[] 크기의 자료를 b[]의 off변수 위치부터 저장하며 len 만큼 읽습니다. 읽은 자료의 바이트 수를 반환합니다. |
void close() | 입력 스트림과 연결된 대상 리소스를 닫습니다. |
안녕 난 Yeppi
// 특정 파일과 연결된 입력스트림 생성
FileInputStream file = new FileInputStream("./data.txt");
int data = 0;
// 더 이상 읽을 데이터가 없을 때까지 데이터를 읽고 출력하는 작업 반복
while ((data = file.read()) != -1) {
System.out.print((char) data);
}
// 입력 스트림 종료
file.close();
출력결과
FileReader
를 사용해야 함??!@?# Yeppi
ABC
fis = new FileInputStream("input.txt");
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
출력결과
A
B
C
ABC
int i;
try(FileInputStream fis = new FileInputStream("input.txt")) {
while((i=fis.read()) != -1) {
System.out.println((char)i);
}
} catch (IOException e) {
System.out.println(e);
}
출력결과
A
B
C
ABCDEFGHIJKLMNOPQRSTUVWXYZ
int i;
try(FileInputStream fis = new FileInputStream("input2.txt")) {
byte[] bs = new byte[10];
// byte 수를 반환
while( (i = fis.read(bs)) != -1 ) {
for(int ch : bs) {
System.out.print((char)ch);
}
System.out.println(" : " + i + "바이트 읽음"); // byte 개수
}
} catch (IOException e) {
System.out.println(e);
}
출력결과
ABCDEFGHIJ : 10바이트 읽음
KLMNOPQRST : 10바이트 읽음
UVWXYZQRST : 6바이트 읽음
ABCDEFGHIJKLMNOPQRSTUVWXYZ
int i;
try(FileInputStream fis = new FileInputStream("input2.txt")) {
byte[] bs = new byte[10];
// byte 수를 반환
while( (i = fis.read(bs)) != -1 ) {
for(int j = 0; j < i; j++) {
System.out.print((char)bs[j]); // 읽은 자료만 반환
}
System.out.println(" : " + i + "바이트 읽음"); // byte 개수
}
} catch (IOException e) {
System.out.println(e);
}
출력결과
ABCDEFGHIJ : 10바이트 읽음
KLMNOPQRST : 10바이트 읽음
UVWXYZ : 6바이트 읽음
문자 단위 입력 스트림, 최상위 추상 클래스
클래스 | 설명 |
---|---|
FileReader | 파일에서 문자 단위로 읽는 스트림 클래스입니다. |
InputStreamReader | 바이트 단위로 읽은 자료를 문자로 변환해주는 보조 스트림 클래스 입니다. |
BufferedReader | 문자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공하는 보조 스트림입니다. |
메서드 | 설명 |
---|---|
int read() | 파일로부터 한 문자를 읽습니다. 읽은 문자를 반환합니다. |
int read(char[] buf) | 파일로부터 buf 배열에 문자를 읽습니다. |
int read(char[] buf, int off, int len) | 파일로부터 buf 배열의 off 위치로부터 len 개수만큼의 문자를 읽습니다. |
void close() | 입력 스트림과 연결된 대상 리소스를 닫습니다. |
안녕 난 Yeppi
// 특정 파일과 연결된 입력스트림 생성
FileReader file = new FileReader ("./data.txt");
int data = 0;
// 더 이상 읽을 데이터가 없을 때까지 데이터를 읽고 출력하는 작업 반복
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
// 입력 스트림 종료
reader.close();
출력결과
안녕 난 Yeppi
바이트 단위 출력 스트림, 최상위 추상 클래스
스트림 클래스 | 설명 |
---|---|
FileOutputStream | 파일에서 바이트 단위로 자료를 씁니다. |
ByteArrayOutputStream | byte 배열 메모리에서 바이트 단위로 자료를 씁니다. |
FilterOutputStream | 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스 |
메서드 | 설명 |
---|---|
int write() | 한 바이트를 출력합니다. |
int write(byte b[]) | b[] 크기의 자료를 출력합니다. |
int write(byte b[], int off, int len) | b[] 배열에 있는 자료의 off 위치부터 len 개수만큼 자료를 출력합니다. |
void flush() | 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력합니다. |
void close() | 출력 스트림과 연결된 대상 리소스를 닫습니다. 자동으로 출력 버퍼가 비워집니다. |
try(FileOutputStream fos = new FileOutputStream("output.txt")) { // 파일 자동 생성
fos.write(65); // A 입력
fos.write(66); // B 입력
fos.write(67); // C 입력
} catch(IOException e) {
System.out.println(e);
}
System.out.println("end");
ABC
FileOutputStream fos = new FileOutputStream("output2.txt");
try(fos) {
byte[] bs = new byte[26];
byte data = 65;
for(int i = 0; i < bs.length; i++) {
bs[i] = data++;
}
fos.write(bs);
} catch(IOException e) {
System.out.println(e);
}
System.out.println("end");
ABCDEFGHIJKLMNOPQRSTUVWXYZ
FileOutputStream fos = new FileOutputStream("output3.txt");
try(fos) {
byte[] bs = new byte[26];
byte data = 65;
for(int i = 0; i < bs.length; i++) {
bs[i] = data++;
}
fos.write(bs, 2, 10); // buffer의 Offset 2, C부터 출력
} catch(IOException e) {
System.out.println(e);
}
System.out.println("end");
CDEFGHIJK
위 코드를 다시 실행하면, overwriting 해서 출력 결과가 같지만
FileOutputStream fos = new FileOutputStream("output3.txt", true);
하면 덧붙여서 데이터가 추가됨
CDEFGHIJK 가 반복되어 추가
파일에 써지는 내용
CDEFGHIJKCDEFGHIJK
문자 단위 출력 스트림, 최상위 추상 클래스
클래스 | 설명 |
---|---|
FileWriter | 파일에서 문자 단위로 출력하는 스트림 클래스입니다. |
OutputStreamWriter | 바이트 단위의 자료를 문자로 변환해 출력해주는 보조 스트림 클래스 입니다. |
BufferedWriter | 문자로 쓸 때 배열을 제공하여 한꺼번에 쓸 수 있는 기능을 제공하는 보조 스트림입니다. |
메서드 | 설명 |
---|---|
int write(int c) | 한 문자를 파일에 합니다. |
int write(char[] buf) | 문자 배열 buf의 내용을 출력합니다. |
int write(char[] buf, int off, int len) | 문자 배열 buf의 off위치에서부터 len 개수의 문자를 출력합니다. |
int write(String str) | 문자열 str을 출력합니다. |
int write(String str, int off, int len) | 문자열 str의 off번째 문자로부터 len 개수만큼 출력합니다. |
int flush() | 출력하기 전에 자료가 있는 공간(출력 버퍼)을 비워 출력하도록 합니다 |
void close() | 스트림과 연결된 리소스를 닫습니다. 출력 버퍼도 비워집니다. |
// 특정 파일과 연결된 출력스트림 생성
FileWriter writer = new FileWriter("./data.txt");
// byte
writer.write(65);
writer.write("\n");
// 한글
writer.write("예");
writer.write('삐');
// 문자열(String)
writer.write("예삐 기술 블로그 경 축 \n");
// 문자 하나 출력
writer.write('A' + " \n");
char buf[] = {'B','C','D','E','F','G'};
// 문자 배열 출력
writer.write(buf);
writer.write("\n");
// 문자 배열의 일부 출력
writer.write(buf, 1, 2);
writer.write("\n");
// 숫자를 그대로 출력
writer.write("65");
// 출력 스트림 종료
writer.close();
A
예삐예삐 기술 블로그 경 축
A
BCDEFG
CD
65
flush()
와 close()
🧐output
에 있는 메서드flush()
close()
close()
메서드 내부에서 flush()가 호출close()
메서드가 호출되면? 출력 버퍼가 비워짐파일로부터 데이터 읽고 쓸 때, 성능 향상을 위한 버퍼를 사용
FileReader 를 통해 데이터를 읽는 경우
메모리 상에 버퍼 생성하여 버퍼 단위로 데이터 읽을 때 사용
기본 생성자
new char[8192]
크기의 문자 버퍼
생성자로 변경 가능
👉 BufferedReader
와 FileReader
는 무조건 결합해서 사용한다고 생각하기
👉 속도 빠르기 때문
System.currentTimeMillis();
long
타입으로 호출 → 엄청 긴 정수 리턴while
문이 돌아가는데 얼마나 걸렸는지 구할 수 있음// 특정 파일과 연결된 스트림 생성
FileReader reader = new FileReader("./src/buffer.java");
BufferedReader buffReader = new BufferedReader(reader);
int data = 0;
// 더 이상 읽을 데이터가 없을 때까지 데이터 읽고 출력하기를 반복
// 시작 시간
long start = System.currentTimeMillis();
while ((data = buffReader.read()) != -1) {
System.out.print((char)data);
}
// 종료 시간
long end = System.currentTimeMillis();
// 스트림 종료
reader.close();
buffReader.close();
System.out.println("소요 시간 -> " + (end - start) + "(ms)초");
출력 결과
public class buffer {
}
소요 시간 -> 1(ms)초
socket의 getInputStream()
을 얻어오고
InputStreamReader()
형태로 감싼 다음
BufferReader()
도 추가로 감싸면?
한글로 소켓 보내기 가능
보조스트림은 계속해서 감쌀 수 있음
마지막 스트림이 최종 스트림으로(기반 스트림)
Socket socket = new Socket();
// 한글로 소켓을 보낼 수 있음
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
br.readLine(); // BufferedReader만 있음, readLine() 한 줄씩 읽기
FileWriter writer = new FileWriter("./a.txt");
BufferedWriter buffWriter = new BufferedWriter(writer);
자세한 예제는
BufferedReader 와 함께 아래 예제에서 살펴보자
FileReader, BufferedReader, FileWriter, BufferedWriter
사용a.txt
파일을 읽어들인 후, b.txt
파일에 출력10,20,30
11,22,33
FileReader reader = new FileReader("./a.txt");
BufferedReader buffReader = new BufferedReader(reader);
FileWriter writer = new FileWriter("./b.txt");
BufferedWriter buffWriter = new BufferedWriter(writer);
String data = null;
int totalCount = 0;
while ((data = buffReader.readLine()) != null) {
String[] scoreList = data.split(",");
int sum = 0;
for(String score : scoreList) {
sum += Integer.parseInt(score);
totalCount++;
}
buffWriter.write(data + ",\t 총점 : " + sum + "\n");
}
buffWriter.write("시험에 응시자 : " + totalCount + "명");
buffWriter.flush();
reader.close();
buffReader.close();
writer.close();
buffReader.close();
10,20,30, 총점 = 60
11,22,33, 총점 = 66
시험에 응시한 학생 수 : 6