[JAVA] 스트림 - 바이트 스트림, 문자 스트림, 버퍼스트림을 이용한 파일 입출력
스트림 입출력
- 버퍼를 가지고 순차적으로 이루어지는 입출력
- 자바의 입출력 스트림 : 응용프로그램과 입출력 장치를 연결하는 소프트웨어 모듈(객체)
컴퓨터 시스템 I/O 연결 구조
자바의 입출력 스트림
- 스트림 양끝에 입출력장치와 자바 응용프로그램 연결
- 스트림은 단방향 (입출력 동시 불가능)
- 선입선출 구조
바이트 스트림
- 입출력되는 데이터를 단순 바이트로 처리
- 단위 byte
문자 스트림
- 문자만 입출력, 바이너리 데이터(이미지, 동영상)는 스트림에서 처리 불가
- 단위 : 문자 (2byte)
- 클래스 (Reader/Writer) (InputStreamReader/OutputStreamWriter) (FileReader/FilerWriter)
FileReader 이용해 파일 읽기
import java.io.*;
public class practice_file1 {
public static void main (String[] args) {
FileReader fin = null;
try {
//파일과 입력바이트 스트림 객체 fin 연결
fin = new FileReader("c:\\windows\\system.ini");
int c;
//파일 전체를 읽어 화면에 출력 (byte씩 c에 읽어들임)
while((c=fin.read())!=-1){ //파일의 끝을 만나면 read()는 -1 리턴
System.out.print((char)c); //byte c 를 문자로 변환하여 출력
}
fin.close();
}
catch(IOException e) {
System.out.println("입출력 오류");
}
}
}
InputStreamReader로 한글 텍스트 파일 읽기
- MS949 사용 (MS에서 만든 한글 확장 완성형 문자 집합)
import java.io.*;
public class practice_file2 {
public static void main(String[] args) {
InputStreamReader in = null;
FileInputStream fin = null;
try {
fin = new FileInputStream("hangul.txt");
in = new InputStreamReader(fin,"UTF-8");
int c;
System.out.println("인코딩 문자 집합은 "+in.getEncoding());
while((c=in.read())!=-1) {
System.out.print((char)c);
}
in.close();
fin.close();
}catch(IOException e) {
System.out.println("입출력 오류");
}
}
}
나는 MS949를 사용해도 한글이 깨진채로 출력됐다. UTF-8로 수정하니 한글이 깨지지 않고 출력되었다.
FileWriter 사용해서 파일 쓰기
- 문자 단위 쓰기 : fout.write(‘A’)
- 블록단위 쓰기 : fout.write(array,0,array.length)
import java.io.*;
import java.util.*;
public class practice_file3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
FileWriter fout = null;
int c;
try {
fout = new FileWriter("text.txt");
while(true) {
String line = sc.nextLine();
if(line.length()==0) break;
fout.write(line,0,line.length());
fout.write("\r\n",0,2); //한 줄 뛰기
}
fout.close();
}catch(IOException e) {
System.out.println("입출력 오류");
}
sc.close();
}
}
바이트 스트림
- 입출력되는 데이터를 단순 바이트로 처리
- 단위 byte
- 클래스
(InputStream/OutputStream) : 추상 클래스, 슈퍼 클래스
(FileInputStream/FileOutputStream) : 바이너리 파일 입출력, 파일로부터 바이트 단위로 읽거나 저장 (DataInputStream/DataOutputStream) : 자바의 기본 data type값(변수)을 바이너리 값 그대로 출력
FileOutputStream으로 바이너리 파일쓰기
package streamStudy;
import java.io.*;
public class practice_file4 {
public static void main(String[] args) {
byte b [] = {7,3,2,-1,65,32};
try {
FileOutputStream fout = new FileOutputStream("test.out");
for(int i=0;i<b.length;i++) {
fout.write(b[i]); //배열 b의 바이너리를 그대로 기록
}
fout.close();
}catch(IOException e) {
System.out.println("오류, 경로명 재확인");
return;
}
System.out.println("test.out 저장 성공");
}
}
cf) 바이너리 파일은 메모장으로 확인 불가
fileOutputStream으로 만든 바이너리 파일 "test.out"를 FileInputStream으로 읽기
package streamStudy;
import java.io.*;
public class practice_file5 {
public static void main(String[] args) {
byte b[] = new byte[6];
try {
FileInputStream fin = new FileInputStream("test.out");
int n=0, c;
while((c=fin.read())!=-1){
b[n]=(byte)c;
n++;
}
for(int i=0;i<b.length;i++) {
System.out.print(b[i]+" ");
}
System.out.println();
fin.close();
}catch(IOException e) {
System.out.println("오류, 경로 재확인");
}
}
}
표준 출력 스트림(System.out)과 연결한 버퍼크기가 5인 버퍼 출력 스트림을 이용한 출력
package streamStudy;
import java.io.*;
import java.util.Scanner;
public class practice_file6 {
public static void main(String[] args) {
FileReader fin = null;
int c;
try {
fin = new FileReader("test.txt");
BufferedOutputStream bout = new BufferedOutputStream(System.out,5);
// 20byte크기의 버퍼 설정. System.out 표준 스트림에 출력
while((c=fin.read())!=-1) {
bout.write(c); //버퍼가 꽉찰때 문자가 화면에 출력
}
//파일 데이터가 모두 출력된 상태
new Scanner(System.in).nextLine(); //enter 키 대기
//enter키를 누르면
bout.flush(); //버퍼에 남아있던 모든 문자 출력
fin.close();
bout.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
추가 예시