티스토리 뷰
Stream의 특징
1. 단일 방향이다
2. FIFO
[ read() 메소드 ]
인자가 없으면 1byte씩만 읽어 온다.
-> 그렇기 때문에 2byte인 한글을 입력하면 두 번에 걸쳐 읽어온다.
인자에 byte형 배열을 써넣으면, 한 번에 최대 배열의 크기만큼 바이트를 읽어들인다.
System.in.read() 메소드에서 입력 시
엔터키를 누르면 \r, \n 두 이스케이프 문자가 입력 된다!!
다양한 타입의 값을 읽어올 수 있도록 하기 위해 추상 메소드이다.
ex)
package StreamEx;
import java.io.*;
public class InputStreamEx {
public static void main(String[] args) {
byte input[] = new byte[5];
int i=0; // 읽어온 바이트의 수
int total = 0; // 총 읽은 바이트의 수
int whileCnt=0; // while문이 실행된 수
try {
while( (i=System.in.read(input)) != -1) { // ctrl+C를 누를 때까지 반복
System.out.println("읽은 바이트 수 : " +i);
System.out.write(input, 0, i); // 읽어온 바이트의 수만큼 input 배열의 값을 출력
System.out.println();
total += i;
whileCnt++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
입력>
strawberry
실행 결과>
읽은 바이트의 수 : 5
straw
읽은 바이트의 수 : 5
berry
읽은 바이트의 수 : 2 \r\n (보이진 않지만 출력됨)
우선 while문의 조건 부분 (i=System.in.read(input)) != -1 를 살펴보자.
System.in.read 메소드의 인자에 byte형 배열이 있으므로,
while문이 한 번 실행될 때마다 입력한 데이터로부터 input 배열의 크기에 따라 최대 5byte만큼 데이터를 읽어온다.
이 때 읽어온 바이트의 수가 i가 된다.
while문을 종료할 때는 ctrl+C 키를 입력하면 -1로 인식되어 while문을 탈출한다.
"strawberry"를 입력하고 엔터키를 누르면 실제로는 "strawberry\r\n" 이 입력된다.
input 배열의 크기가 5이기 때문에 while문 내에서 읽어들일 수 있는 최대 i 값은 5이다.
while문이 첫 번째 실행되면 다섯 글자를 읽어와 "straw" 가 출력되고, 그 다음에는 "berry"가 출력되며, 한번 더 while문이 실행되어 "\r\n"이 출력된다.
따라서, 총 읽어들인 글자 수(total)는 12이다.
[FileInputStream]
ex)
Java
IOStream
Practice!!
해당 패키지 폴더에 test.txt 저장
package StreamEx;
import java.io.*;
public class FileInputEx {
public static void main(String[] args) {
FileInputStream in = null;
try {
in = new FileInputStream("test.txt");
int n;
int cnt=0;
while((n = in.read()) != -1) { // 한 글자씩 읽어 들임
System.out.print((char)n);
cnt++;
}
System.out.println("전체 바이트 수 : "+cnt);
in.close();
} catch (IOException e) {
System.out.println("입출력 오류");
}
}
}
실행 결과>
Java
IOStream
Practice!!
전체 바이트 수 : 26
while문이 한 번 실행될 때마다 test.txt 의 내용을 한 글자씩 읽어와 출력한다.
while문을 빠져나오면 while문이 실행된 횟수, 즉 test.txt의 총 바이트 수(cnt)가 출력된다.
test.txt의 내용은
Java\r\n
IOStream\r\n
Practice!!
이므로 총 6+10+10 = 26 바이트이다.
[FileOutputStream]
write() 메소드로 OutputStream에 데이터를 쓰고,
flush() 메소드를 사용해 스트림에 있는 데이터를 파일에 출력한다(쓴다).
ex)
package StreamEx;
import java.io.*;
public class FileOutputEx {
public static void main(String[] args) {
try {
// 인자에 true => test.txt 파일에 덧붙여 쓸 수 있도록 함
FileOutputStream fo = new FileOutputStream("test.txt", true);
int n=0;
while( (n=System.in.read()) != -1) {
fo.write(n);
fo.flush(); // 스트림에 있는 데이터를 출력
}
System.in.close();
fo.close();
} catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
FileOutputStream 의 첫 번째 생성자에는 출력할 파일명을 쓰고, 두 번째 생성자에 true를 쓰면 해당 파일의 내용에 덧붙여서 쓰도록 하겠다는 의미이다.
문자열을 입력하면 System.in.read()에서 한 글자씩 읽어들이고, 그 읽어들인 값을 fo에 write한다.
심화) 파일 내용을 다른 파일에 복사하기
package StreamEx;
import java.io.*;
public class FileCopy {
public static void main(String[] args) throws IOException {
FileInputStream fi = new FileInputStream("복사할것.jpg");
FileOutputStream fo = new FileOutputStream("복사당할것.jpg");
byte buf[] = new byte[1024];
int n = 0;
int whileCnt = 0;
int totalByte = 0;
while((n=fi.read(buf)) != -1) { // fi로부터 읽은 데이터를 buf에 저장
fo.write(buf, 0, n); // buf의 n byte 데이터를 OutputStream에 씀
fo.flush(); // OutputStream에 쓴 데이터를 파일에 출력
whileCnt++;
totalByte+=n;
}
System.out.println("while문 반복 수: "+whileCnt);
System.out.println("복사된 바이트 수: "+totalByte);
fi.close();
fo.close();
}
}
해당 패키지에 복사할것.jpg, 복사당할것.jpg 라는 파일이 존재한다.
while문에서 복사할것.jpg 파일로부터 buf의 크기인 1024 바이트씩 데이터를 읽어와 buf 배열에 저장한다.
그런 다음 buf 배열에서 n byte만큼의 데이터를 OutputStream에 write한다.
그리고 flush 메소드를 이용해 OutputStream에 있는 데이터를 복사당할것.jpg 파일에 출력한다.
복사할것.jpg 파일의 모든 데이터를 읽으면 while문을 빠져나온다.
그런 다음 두 파일을 확인해보면 복사당할것.jpg 파일의 내용이 복사할것.jpg의 내용으로 복사된 것을 확인할 수 있다.
'Java, JavaScript' 카테고리의 다른 글
[Java] BufferedIOStream, DataIOStream (0) | 2019.07.01 |
---|---|
[Java] ByteArrayStream, PipedStream (0) | 2019.06.28 |
[Java] Collections Framework - Map (0) | 2019.06.18 |
[Java] Collections Framework - Collection(List, Set) (0) | 2019.06.18 |
[Java] Generic (0) | 2019.06.14 |