728x90
2023.01.30 - [JAVA/Java 기초] - 입출력 스트림.java
입출력 스트림.java
입력 스트림과 출력 스트림 프로그램을 기준으로 데이터가 들어오면 입력 스트림, 데이터가 나가면 출력 스트림 프로그램이 다른 프로그램과 데이터를 교환하려면 양쪽 모두 입력 스트림과 출
less-go.tistory.com
이전 글에서 이어집니다.
문자 출력
- Writer는 문자 출력 스트림의 최상위 클래스로, 추상 클래스입니다.
- 모든 문자 출력 스트림 클래스는 Writer 클래스를 상속받아서 만들어 집니다.

WriteExam.java
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class WriteExam {
public static void main(String[] args) {
try {
Writer writer = new FileWriter("c:/Temp/test.txt");
// 문자를 파일로 출력
char a = 'A';
writer.write(a);
char b = 'B';
writer.write(b);
// 배열을 파일로 출력
char[] arr = { 'C', 'D', 'E'};
writer.write(arr);
// 문자열을 파일로 출력
writer.write("FGH");
writer.flush(); // 버퍼 비우기
writer.close(); // 메모리 정리
}catch (IOException e) {
e.getStackTrace();
}
}
}
결과:
test.txt 파일이 생성되었습니다.
내용 : ABCDEFGH
Reader
- Reader는 문자 입력 스트림의 최상위 클래스로, 추상클래스 입니다.
- 모든 문자 입력 스트림 클래스는 Reader 클래스를 상속받아서 만들어 집니다.

- Reader 클래스에는 문자 입력 스트림이 기본적으로 가져야할 메소드가 정의되어 있습니다.

ReadExam.java
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class ReadExam {
public static void main(String[] args) {
try {
Reader reader = null;
reader = new FileReader("c:/Temp/test.txt");
// 한 문자씩 읽기
while(true) {
int data = reader.read(); // .read() 한 문자 씩 읽어 들인다.
if(data == -1) break; // -1, 더이상 읽을 데이터가 없을때 break
System.out.println((char)data);
// char형으로 문자 하나씩 출력
}
reader.close();
System.out.println();
// 문자 배열로 읽기
reader = new FileReader("c:/Temp/test.txt");
char[] data = new char[100]; //100개의 문자를 읽어 들인다.
while(true) {
int num = reader.read(data); //.read(data) 100 문자 씩 읽어 들입니다.
if(num==-1) break; // -1 더이상 읽을 데이터가 없을때 break;
for(int i=0; i<num; i++) {
System.out.println(data[i]);
}
}
reader.close();
}catch(FileNotFoundException e) {
e.getStackTrace();
}catch(IOException e) {
e.getStackTrace();
}
}
}
결과:
A
B
C
D
E
F
G
H
A
B
C
D
E
F
G
H
보조 스트림
- 다른 스트림과 연결되어 여러 편리한 기능을 제공해 주는 스트림.
- 자체적으로 입출력을 수행할 수 없기 때문에 입출력 소스로부터 직접 생성된 입출력 스트림에 연결해서 사용합니다.

- 입출력 스트림에 보조 스트림을 연결하려면 보조 스트림을 생성할 때 생성자 매개값으로 입출력 스트림을 제공합니다.
보조스트림 변수 = new 보조스트림(입출력스트림);
- 보조 스트림은 또 다른 보조 스트림과 연결되어 스트림 체인으로 구성할 수 있습니다.

보조스트림2 변수 = new 보조스트림2(보조스트림1);

InputStream을 Reader로 변환
- InputStream을 Reader로 변환하려면 InputStreamReader 보조 스트림을 연결합니다.


OutputStream을 Writer로 변환
- OutputStream을 Writer로 변환 하려면 OutputStreamWriter 보조 스트림을 연결합니다.


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
public class CharacterConvertStreamExam {
public static void main(String[] args) throws Exception{
write("예아쓰 베이베");
String data = read();
System.out.println(data);
}
public static void write(String str) throws Exception{
OutputStream os = new FileOutputStream("C:/Temp/test.txt");
Writer writer = new OutputStreamWriter(os, "UTF-8"); //출력 인코딩 지정
writer.write(str);
writer.flush();
writer.close();
}
public static String read() throws Exception {
InputStream is = new FileInputStream("C:/Temp/test.txt");
Reader reader = new InputStreamReader(is, "UTF-8");
char[] data = new char[100];
int num = reader.read(data);
reader.close();
String str = new String(data, 0, num);
//Char 배열에서 읽은 문자 수만큼 문자열로 변환
return str;
}
}
결과:
test.txt 파일 생성후, 예아쓰 베이베 출력
메모리 버퍼로 실행 성능을 높이는 보조 스트림
- 프로그램이 중간에 메모리 버퍼(buffer)와 작업해서 실행 성능 향상 가능
- 출력 스트림의 경우 직접 하드디스크에 데이터를 보내지 않고 메모리 버퍼에 데이터를 보냄으로써 출력 속도를 향상시킵니다. 입력 스트림에서도 버퍼를 사용하면 읽기 성능이 향상됩니다.


- 바이트 스트림에는 BufferedInputStream, BufferedOutputStream 이 있고,
- 문자 스트림에는 BufferedReader, BufferdWriter가 있습니다.
BufferedInputStream bis = new BufferedInputStream(바이트 입력 스트림);
BufferedOutputStream bos = new BufferedOutputStream(바이트 출력 스트림);
BufferedReader br = new BufferedReader(문자 입력 스트림);
BufferedWriter bw = new BufferedWriter(문자 출력 스트림);
성능 향상 보조 스트림(BufferedInputStream, BufferedOutputStream)을 사용해서 파일복사 성능차이를 확인해 봅시다.
originFile1.jpg, originFile2.jpg 를 해당 프로젝트의 bin 폴더 -> 해당 패키지에 복사해둔 후 시작합니다.
package IO1;
import java.io.*;
public class BufferExam {
public static void main(String[] args) throws Exception{
//입출력 스트림 생성
String originFilePath1 =
BufferExam.class.getResource("originFile1.jpg").getPath();
String targetFilePath1 = "c:/Temp/targetFile1.jpg";
FileInputStream fis = new FileInputStream(originFilePath1);
FileOutputStream fos = new FileOutputStream(targetFilePath1);
//입출력 스트림 + 버퍼 스트림 생성
String originFilePath2 =
BufferExam.class.getResource("originFile2.jpg").getPath();
String targetFilePath2 = "c:/Temp/targetFile2.jpg";
FileInputStream fis2 = new FileInputStream(originFilePath2);
FileOutputStream fos2 = new FileOutputStream(targetFilePath2);
BufferedInputStream bis = new BufferedInputStream(fis2);
BufferedOutputStream bos = new BufferedOutputStream(fos2);
//버퍼를 사용하지 않고 복사
long nonBufferTime = copy(fis, fos);
System.out.println("버퍼 미사용:\t" + nonBufferTime + " ns");
//버퍼를 사용하고 복사
long bufferTime = copy(bis, bos);
System.out.println("버퍼 사용: \t" + bufferTime + " ns");
fis.close();
fos.close();
bis.close();
bos.close();
}
public static long copy(InputStream is, OutputStream os) throws Exception{
//시작 시간 저장
long start = System.nanoTime();
//1바이트를 읽고 1바이트를 출력
while(true) {
int data = is.read();
if(data == -1) break;
os.write(data);
}
os.flush();
//끝 시간 저장
long end = System.nanoTime();
//복사 시간 리턴
return (end-start);
}
}
결과 :
버퍼 미사용: 3487992100 ns
버퍼 사용: 35583300 ns
문자 입력 스트림 Reader에 BufferedReader를 연결하면 성능 향상 뿐만 아니라 행 단위로 문자열을 읽는 아주 편리한 기능인 readLine()메소드를 제공합니다.
다음은 문자 파일을 행 단위로 읽는 코드입니다.
BuffredReader br = new BufferedReader(
new FileReader("c:/javawork/java1214/src/java1214/television.java"));
while(true){
String str = br.readLine();
if(str == null) break;
}
import java.io.*;
public class ReadLineExam {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader("c:/javawork/java1214/src/java1214/television.java"));
int lineNo =1;
while(true) {
String str = br.readLine(); // readLine()은 파일의 한줄 단위로 읽어 들입니다.
if(str == null) break;
System.out.println(lineNo + "\t" + str); // 한줄씩 출력
lineNo++;
}
br.close();
}
}
결과:
1 package java1214;
2
3 class MyTv {
4 boolean isPowerOn;
5 int channel;
6 int volume;
7
8 final int MAX_VOLUME = 100;
9 final int MIN_VOLUME = 0;
10 final int MAX_CHANNEL = 100;
11 final int MIN_CHANNEL = 1;
12
13 void turnOnOff() {
14 // isPowerON의 값이 true면 false로, false면 true로 바꾼다.
15 }
16 void volumeUp() {
17 // volume의 값이 MAX_VOLUME보다 작을 때만 값을 1 증가시킨다.
18 }
19 void volumeDown() {
20 // volume의 값이 MIN_VOLUME보다 클 때만 값을 1 감소시킨다.
21 }
22 void channelUp() {
23 // channel의 값을 1 증가 시킨다.
24 // 만일 channel이 MAX_CHANNEL이면, channel의 값을 MIN_CHANNEL로 바꾼다.
25 }
26 void channelDown() {
27 // channel의 값을 1 감소시킨다.
28 // channel이 MIN_CHANNEL이면, channel의 값을 MAX_CHANNEL로 바꾼다.
29 }
30 }//class MyTV
31
32 public class television {
33 public static void main(String[] args) {
34 MyTv t = new MyTv();
35
36 t.channel = 100;
37 t.volume = 0;
38 System.out.println("CH:" + t.channel + ", VOL:" + t.volume);
39
40 t.channelDown();
41 t.volumeDown();
42 System.out.println("CH:" + t.channel + ", VOL:" + t.volume);
43
44 t.volume = 100;
45 t.channelUp();
46 t.volumeUp();
47 System.out.println("CH:" + t.channel + ", VOL:" + t.volume);
48
49 }
50 }
728x90
'JAVA > Java 기초' 카테고리의 다른 글
| 기본 타입 스트림.java (0) | 2023.01.31 |
|---|---|
| 요소 커스텀 집계.java (0) | 2023.01.30 |
| 입출력 스트림.java (0) | 2023.01.30 |
| Optional 클래스.java (0) | 2023.01.30 |
| 루핑, 매칭, 집계.java (0) | 2023.01.30 |