[JAVA] 파일 입출력
스트림 (stream)
[도착지] [출발지]
Program <--- InputStream <--- Source(Keyboard, Mouse, File, Network)
[출발지] [도착지]
Program ---> OutputStream ---> Destination(Monitor, Beam, File, Network)
java.io 패키지의 주요 클래스
1) 바이트(byte) 단위 입출력 스트림 클래스
java.io.InputStream: 프로그램이 '바이트 단위' 데이터를 읽어들이는(read) 통로
java.io.OutputStream: 프로그램이 '바이트 단위' 데이터를 쓰는(write) 통로
** 위 두개 클래스는 '추상클래스' 다
2) 문자(character) 단위 입출력 스트림 클래스
java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로
3) java.io.File : 파일 시스템의 파일정보를 얻기 위한 클래스
4) java.io.Console : 콘솔로부터 문자을 입출력하기 위한 클래스
public class File01Main {
public static void main(String[] args) {
System.out.println("IO(Input/Output)");
// InputStream 객체 in을 가지고 읽어들일 수 있는 스캐너 객체 생성
Scanner sc = new Scanner(System.in);
// 외부장치(콘솔, 키보드)로부터 데이터를 읽음
String msg = sc.nextLine();
sc.close();
// OutpustStream 객체인 out이 가지고 있는 println() 메소드를 사용
// 외부장치(콘솔, 모니터)에 데이터를 씀
System.out.println(msg);
System.out.println("\n프로그램 종료");
} // end main()
} // end class
* FileIO
Program <=== InputStream <=== Source
Program ===> OutputStream ===> Source
Program <=== FileInputStream <=== File
Program ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FileInputStream: 파일로부터 데이터를 읽어오는 통로
java.io.OutputStream
|__ java.io.FileOutputStream: 파일로 데이터를 쓰는 통로
package com.lec.java.file02;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* FileIO
Program <=== InputStream <=== Source
Program ===> OutputStream ===> Source
Program <=== FileInputStream <=== File
Program ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FileInputStream: 파일로부터 데이터를 읽어오는 통로
java.io.OutputStream
|__ java.io.FileOutputStream: 파일로 데이터를 쓰는 통로
*/
public class File02Main {
public static void main(String[] args) {
System.out.println("File IO");
InputStream in = null;
OutputStream out = null;
try {
// FileInputStream 인스턴스 생성
in = new FileInputStream("temp/big_text.txt");
// FileOutputStream 인스턴스 생성
// 해당 파일이 없으면, 새로생성.
// .. 있었으면, 지우고 새로생성.
out = new FileOutputStream("temp/copy_big_text.txt");
// 파일복사
// InputStream 에서 한 byte 씩 읽어 들여와서
// OutputStream 에 한 byte 씩 쓰기.
int dataRead;
int byteCopied = 0;
long startTime = System.currentTimeMillis(); // 현재 시간 저장
while(true) {
// 데이터 읽기: InputStream에 있는 read() 메소드 사용
// read()는 InputStream 으로부터
// 1byte 씩 읽어서 int(4byte) 에 담아 리턴한다
// [ ... ][ ... ][ ... ][ 1byte ]
dataRead = in.read();
if(dataRead == -1) { // 더이상 읽을 것이 없으면 read() 는 -1 을 리턴한다.
break;
}
// 데이터 쓰기: OutputStream에 있는 write() 메소드 사용
// write() 는
// int(4byte)에 1byte씩 담아 OutputStream에 쓴다
// [ ... ][ ... ][ ... ][ 1byte ]
out.write(dataRead);
byteCopied++;
} // end while
long endTime = System.currentTimeMillis(); // 끝난 시간 저장
long elapsedTime = endTime - startTime; // 경과 시간
System.out.println("읽고 쓴 바이트: " + byteCopied);
System.out.println("경과 시간(ms): " + elapsedTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 리소스 해제
try {
if(out != null) out.close();
if(in != null) in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
Java 7부터 도입된 try-with-resource
try (리소스 생성) { ... }
catch (exception ) { ... }
리소스를 close하는 코드가 없어도 자동으로 close가 실행
java.lang.AutoCloseable 나
└─ java.io.Closeable 을 상속받은 어떠한 객체라도
try(리소스 생성) 안에 '선언' 되어 있으면
try~catch 가 끝나기 전에 close() 됨.
InputStream, OutputStream 둘다 Closeable 을 상속(implements) 한다
package com.lec.java.file03;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/*
java.io.InputStream
|__ java.io.FileInputStream
java.io.OutputStream
|__ java.io.FileOutputStream
*/
public class File03Main {
public static void main(String[] args) {
System.out.println("File IO 2");
// Java 7부터 도입된 try-with-resource
// try (리소스 생성) { ... }
// catch (exception ) { ... }
// 리소스를 close하는 코드가 없어도 자동으로 close가 실행
//
// java.lang.AutoCloseable 나
// └─ java.io.Closeable 을 상속받은 어떠한 객체라도
// try(리소스 생성) 안에 '선언' 되어 있으면
// try~catch 가 끝나기 전에 close() 됨.
// InputStream, OutputStream 둘다 Closeable 을 상속(implements) 한다
try(
// FileInputStream 생성
InputStream in = new FileInputStream("temp/big_text.txt");
OutputStream out = new FileOutputStream("temp/copy_big_text.txt");
){
byte[] buff = new byte[1024]; // 버퍼 준비
int lengthRead = 0; // 버퍼에 담긴 byte수
int byteCopied = 0;
long startTime = System.currentTimeMillis();
// 파일복사
while(true) {
// 데이터 읽기
// 매개변수로 주어진 byte[] 배열의 길이 만큼 read한다.
// 실제 읽어 들인 데이터는 매개변수 byte[] 에 담김.
// 읽어들인 바이트 개수 리턴, 읽어들인게 없으면 -1 리턴.
lengthRead = in.read(buff);
if(lengthRead == -1) { // 더이상 읽어들일 것이 없으면 종료
break;
}
// 데이터 쓰기
out.write(buff, 0, lengthRead); // 직전에 읽어들인 데이터만큼 write
byteCopied += lengthRead;
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("전체 복사한 바이트: " + byteCopied);
System.out.println("경과 시간: " + elapsedTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
보조스트림 (filter stream)
Program <=== FilterInputStream <=== InputStream <=== Source
↓ 상속 ↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File
Program ===> FilterOutputStream ===> OutputStream ===> Source
↓ 상속 ↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FilterInputStream
|__ java.io.BufferedInputStream
java.io.OutputStream
|__ java.io.FilterOutputStream
|__ java.io.BufferedOutputStream
참고 ) 보조스트림 (filter stream)
보조스트림(filter stream) 이란 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림
package com.lec.java.file04;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* 보조스트림 (filter stream)
Program <=== FilterInputStream <=== InputStream <=== Source
↓ 상속 ↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File
Program ===> FilterOutputStream ===> OutputStream ===> Source
↓ 상속 ↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FilterInputStream
|__ java.io.BufferedInputStream
java.io.OutputStream
|__ java.io.FilterOutputStream
|__ java.io.BufferedOutputStream
참고 ) 보조스트림 (filter stream)
보조스트림(filter stream) 이란 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림
*/
public class File04Main {
public static void main(String[] args) {
System.out.println("BufferedInputStream, BufferedOutputStream");
InputStream in = null;
BufferedInputStream bin = null;
OutputStream out = null;
BufferedOutputStream bout = null;
try {
// FileInputStream 인스턴스 생성
in = new FileInputStream("temp/big_text.txt");
bin = new BufferedInputStream(in); // 장착!
// FileOutputStream 인스턴스 생성
// 해당 파일이 없으면, 새로생성.
// .. 있었으면, 지우고 새로생성.
out = new FileOutputStream("temp/copy_big_text.txt");
bout = new BufferedOutputStream(out); // 장착!
// in.read() 대신에 bin.read() 를
// out.write() 대신에 bout.write() 를 사용하면 된다.
// finally 꼭!
// 파일복사
int dataRead;
int byteCopied = 0;
long startTime = System.currentTimeMillis(); // 현재 시간 저장
while(true) {
dataRead = bin.read();
if(dataRead == -1) {
break;
}
bout.write(dataRead);
byteCopied++;
} // end while
long endTime = System.currentTimeMillis(); // 끝난 시간 저장
long elapsedTime = endTime - startTime; // 경과 시간
System.out.println("읽고 쓴 바이트: " + byteCopied);
System.out.println("경과 시간(ms): " + elapsedTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 리소스 해제
try {
if(bout != null) bout.close();
if(bin != null) bin.close();
// bin 을 close() 하면 bin 이 장착된 in 도 함께 close된다.
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
package com.lec.java.file05;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* Buffered Stream + Buffer 예제
Program <=== FilterInputStream <=== InputStream <=== Source
↓ 상속 ↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File
Program ===> FilterOutputStream ===> OutputStream ===> Source
↓ 상속 ↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FilterInputStream
|__ java.io.BufferedInputStream
java.io.OutputStream
|__ java.io.FilterOutputStream
|__ java.io.BufferedOutputStream
*/
public class File05Main {
public static void main(String[] args) {
System.out.println("Buffered Stream + Buffer");
// TODO:
// file03 패키지 참조
// try with resource 구문으로 작성
// in.read(buff) --> bin.read(buff);
// out.write( , , ) --> bout.write( , , ); 사용
// finally 필요 없슴
try(
// FileInputStream 생성
InputStream in = new FileInputStream("temp/big_text.txt");
BufferedInputStream bin = new BufferedInputStream(in); // 장착
OutputStream out = new FileOutputStream("temp/copy_big_text.txt");
BufferedOutputStream bout = new BufferedOutputStream(out);
){
byte[] buff = new byte[1024]; // 버퍼 준비
int lengthRead = 0; // 버퍼에 담긴 byte수
int byteCopied = 0;
long startTime = System.currentTimeMillis();
// 파일복사
while(true) {
// 데이터 읽기
lengthRead = bin.read(buff);
if(lengthRead == -1) { // 더이상 읽어들일 것이 없으면 종료
break;
}
// 데이터 쓰기
bout.write(buff, 0, lengthRead); // 직전에 읽어들인 데이터만큼 write
byteCopied += lengthRead;
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("전체 복사한 바이트: " + byteCopied);
System.out.println("경과 시간: " + elapsedTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class File05Main
package com.lec.java.file06;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* Data Filter Stream
Program <=== DataInputStream <=== FileInputStream <=== File
Program ===> DataOutputStream ===> FileOutputStream ===> File
java.io.InputStream
|__ java.io.FilterInputStream
|__ java.io.DataInputStream
java.io.OutputStream
|__ java.io.FilterOutputStream
|__ java.io.DataOutputStream
*/
public class File06Main {
public static void main(String[] args) {
System.out.println("Data Filter Stream");
try(
OutputStream out = new FileOutputStream("temp/data.bin");
DataOutputStream dout = new DataOutputStream(out);
InputStream in = new FileInputStream("temp/data.bin");
DataInputStream din = new DataInputStream(in);
){
dout.writeBoolean(true); // 1 byte
dout.writeInt(100); // 4 byte
dout.writeDouble(3.14); // 8 byte
dout.writeChar('A'); // 2 byte
boolean b = din.readBoolean();
System.out.println("boolean: " + b);
int num1 = din.readInt();
System.out.println("int: " + num1);
double num2 = din.readDouble();
System.out.println("double: " + num2);
char ch = din.readChar();
System.out.println("char: " + ch);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
Object Filter Stream
Program <=== ObjectInputStream <=== FileInputStream <=== File
Program ===> ObjectOutputStream ===> FileOutputStream ===> File
java.lang.Object
└─ java.io.OutputStream
└─ java.io.ObjectOutputStream
java.lang.Object
└─ java.io.InputStream
└─ java.io.ObjectInputStream
Object Stream: 객체의 입출력을 위한 스트림
사용법은 다른 Filter Stream(Buffered I/O, Data I/O)과 비슷
Object 스트림의 입출력 대상이 되는 클래스는 Serializable 인터페이스를 구현
클래스의 일부 멤버 변수를 직렬화(Serialization)의 대상에서 제외시키려면, transient 키워드를 사용
package com.lec.java.file08;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/* Object Filter Stream
Program <=== ObjectInputStream <=== FileInputStream <=== File
Program ===> ObjectOutputStream ===> FileOutputStream ===> File
java.lang.Object
└─ java.io.OutputStream
└─ java.io.ObjectOutputStream
java.lang.Object
└─ java.io.InputStream
└─ java.io.ObjectInputStream
Object Stream: 객체의 입출력을 위한 스트림
사용법은 다른 Filter Stream(Buffered I/O, Data I/O)과 비슷
Object 스트림의 입출력 대상이 되는 클래스는 Serializable 인터페이스를 구현
클래스의 일부 멤버 변수를 직렬화(Serialization)의 대상에서 제외시키려면,
transient 키워드를 사용
*/
public class File08Main {
public static final String FILEPATH = "temp/member.dat";
public static void main(String[] args) {
System.out.println("Object Filter Stream");
try(
OutputStream out = new FileOutputStream(FILEPATH);
ObjectOutputStream oout = new ObjectOutputStream(out);
InputStream in = new FileInputStream(FILEPATH);
ObjectInputStream oin = new ObjectInputStream(in);
){
// 파일에 저장할 데이터 객체 생성
Member m1 = new Member("root", "root1234");
Member m2 = new Member("quest", "quest");
Member m3 = new Member("admin", "admin123456");
oout.writeObject(m1);
oout.writeObject(m2);
oout.writeObject(m3);
// 파일에서 Object 타입으로 읽기
Member dataRead;
dataRead = (Member)oin.readObject();
dataRead.displayInfo();
dataRead = (Member)oin.readObject();
dataRead.displayInfo();
dataRead = (Member)oin.readObject();
dataRead.displayInfo();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
package com.lec.java.file08;
import java.io.Serializable;
public class Member implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4564811082080172359L;
private String id;
private String pw;
transient private int num;
transient private boolean isExist;
// transient로 선언된 변수는 serialization(직렬화) 대상에서 제외됨.
// (파일에 write되지 않는다)
// de-serializtion(역직렬화, 파일에서 읽기)를 할 때는
// 해당 타입의 기본값(0, false, null)으로 초기화됨
public Member() {}
public Member(String id, String pw) {
this.id = id;
this.pw = pw;
this.num = 123;
this.isExist = true;
}
public void displayInfo() {
System.out.println("--- 회원 정보 ---");
System.out.println("아이디: " + id);
System.out.println("비밀번호: " + pw);
System.out.println("번호: " + num);
System.out.println("Exist? " + isExist);
}
} // end class Member
Object Filter Stream + Collection
Program <=== ObjectInputStream <=== FileInputStream <=== File
Program ===> ObjectOutputStream ===> FileOutputStream ===> File
ArrayList<> 와 같은 Collection 에서,
모든 데이터들이 Serializable 되어 있으면 ObjectInputStream / ObjectOutputStream 으로 read/write 가능.
package com.lec.java.file09;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
// Object Filter Stream + Collection
// Program <=== ObjectInputStream <=== FileInputStream <=== File
// Program ===> ObjectOutputStream ===> FileOutputStream ===> File
// ArrayList<> 와 같은 Collection 에서,
// 모든 데이터들이 Serializable 되어 있으면 ObjectInputStream / ObjectOutputStream 으로
// read/write 가능.
public class File09Main {
public static final String FILEPATH = "temp/member2.dat";
public static void main(String[] args) {
System.out.println("Object Filter Stream");
try(
OutputStream out = new FileOutputStream(FILEPATH);
ObjectOutputStream oout = new ObjectOutputStream(out);
InputStream in = new FileInputStream(FILEPATH);
ObjectInputStream oin = new ObjectInputStream(in);
){
// 리스트 준비
ArrayList<Member> list = new ArrayList<Member>();
// 파일에 저장할 데이터 객체 생성
Member m1 = new Member("root", "root1234");
Member m2 = new Member("quest", "quest");
Member m3 = new Member("admin", "admin123456");
list.add(m1);
list.add(m2);
list.add(m3);
oout.writeObject(list); // List 를 한번에 저장
list = null;
list = (ArrayList<Member>)oin.readObject();
for(Member m : list) {
m.displayInfo();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class File08Main
package com.lec.java.file09;
import java.io.Serializable;
public class Member implements Serializable {
/**
*
*/
private static final long serialVersionUID = -362426577793734250L;
private String id;
private String pw;
transient private int num;
transient private boolean isExist;
// transient로 선언된 변수는 serialization(직렬화) 대상에서 제외됨.
// (파일에 write되지 않는다)
// de-serializtion(역직렬화, 파일에서 읽기)를 할 때는
// 해당 타입의 기본값(0, false, null)으로 초기화됨
public Member() {}
public Member(String id, String pw) {
this.id = id;
this.pw = pw;
this.num = 123; // de-serializtion 동작 확인을 위해 기본값 초기화
this.isExist = true;
}
public void displayInfo() {
System.out.println("--- 회원 정보 ---");
System.out.println("아이디: " + id);
System.out.println("비밀번호: " + pw);
System.out.println("번호: " + num);
System.out.println("Exist? " + isExist);
}
} // end class Member
문자(character) 단위 입출력 스트림 클래스
java.io.Reader : 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
└─ java.io.InputStreamReader
└─ java.io.FileReader
java.io.Writer : 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로
└─ java.io.OutputStreamWriter
└─ java.io.FileWriter
FileReader / FileWriter 객체는 '텍스트파일, 즉 문자 단위' 데이터를 읽고/쓰기 할때 사용하는 기반 스트립 입니다.
따라서 텍스트가 아닌 오디오, 비디오, 등의 파일을 다룰수 없습니다.
주로 String 이나 char [] 내용을 입/출력 할때 사용합니다.
텍스트 파일 (Text File) 이란
사람이 읽을수 있는 글자들이 저장된 파일
암호화 되지 않은 평범한 텍스트
이진파일 (Binary File) 이란
사람이 직접 읽을수는 없음.
★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
package com.lec.java.file11;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
/*
문자(character) 단위 입출력 스트림 클래스
java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
└─ java.io.InputStreamReader
└─ java.io.FileReader
java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로
└─ java.io.OutputStreamWriter
└─ java.io.FileWriter
FileReader / FileWriter 객체는 '텍스트파일, 즉 문자 단위' 데이터를 읽고/쓰기 할때
사용하는 기반 스트립 입니다. 따라서 텍스트가 아닌 오디오, 비디오, 등의 파일을 다룰수 없습니다.
주로 String 이나 char [] 내용을 입/출력 할때 사용합니다.
텍스트 파일 (Text File) 이란
사람이 읽을수 있는 글자들이 저장된 파일
암호화 되지 않은 평범한 텍스트
이진파일 (Binary File) 이란
사람이 직접 읽을수는 없슴.
★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
*/
public class File11Main {
public static void main(String[] args) {
System.out.println("FileReader / FileWriter");
String src = "temp/FileData.txt";
String dst = "temp/FileData.txt";
// FileWriter fw = null;
// FileReader fr = null;
try(
FileWriter fw = new FileWriter(dst);
FileReader fr = new FileReader(src);
// byte 스트림 방식과 비교
OutputStream out = new FileOutputStream("temp/FileData.bin");
DataOutputStream dout = new DataOutputStream(out);
) {
String str = "안녕하세요"; // 한글 5글자
char [] charArr = {'J', 'A', 'V', 'A'}; // 알파벳 4글자
// Writer 는 주로 문자열(String) 이나 char [] 의 내용을 출력할때 사용
fw.write(str); // 저장은 시스템 인코딩 상태에 따라 저장됨.
fw.write(charArr); // UTF-8 인코딩의 경우 한글 한글자당 3byte, 영어는 한글자당 1byte
fw.flush(); // flush() 메소드로 출력버퍼의 데이터를 완전히 출력
// 읽기 read
char [] buff = new char[100]; // 읽어들일 버퍼 준비
int charsRead = fr.read(buff); // 최대 buff 만큼의 텍스트 읽어들임. 읽은 문자개수 리턴
for(int i = 0; i < charsRead; i++) {
System.out.print(buff[i]);
}
System.out.println();
System.out.println("읽은 문자 개수: " + charsRead);
// byte 스트림으로 저장하기
dout.writeChars(str);
for(char ch : charArr) {
dout.writeChar(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
// finally {
// try {
// if(fw != null) fw.close();
// if(fr != null) fr.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
System.out.println("\n프로그램 종료");
} // end main()
} // end class
버퍼사용 문자입출력 : BufferedReader, BufferedWriter
java.lang.Object
└─ java.io.Reader
└─ java.io.BufferedReader
java.lang.Object
└─ java.io.Writer
└─ java.io.BufferedWriter
★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
package com.lec.java.file12;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 버퍼사용 문자입출력 : BufferedReader, BufferedWriter
*
* java.lang.Object
* └─ java.io.Reader
* └─ java.io.BufferedReader
*
* java.lang.Object
* └─ java.io.Writer
* └─ java.io.BufferedWriter
*
* ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
*
*/
/*
* txt 는 utf-8 로 인코딩 , 영문 텍스트
*/
public class File12Main {
private static final String BIG_TEXT = "temp/big_eng.txt";
public static void main(String[] args) {
System.out.println("FileReader / FileWriter");
try(
FileReader fr = new FileReader(BIG_TEXT);
FileWriter fw = new FileWriter("temp/big_eng_copy1.txt");
FileReader fr2 = new FileReader(BIG_TEXT);
FileWriter fw2 = new FileWriter("temp/big_eng_copy2.txt");
BufferedReader br = new BufferedReader(fr2); // 장착!
BufferedWriter bw = new BufferedWriter(fw2);
){
System.out.println("FileReader/FileWriter 만 사용");
int charRead = 0;
int charsCopied = 0;
long startTime = System.currentTimeMillis();
// while(true) {
// charRead = fr.read();
// if(charRead == -1) break;
// fw.write(charRead);
// charsCopied++;
// }
while((charRead = fr.read()) != -1) {
fw.write(charRead);
charsCopied++;
}
fw.flush();
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("읽고 쓴 문자수: " + charsCopied);
System.out.println("경과시간(ms): " + elapsedTime);
System.out.println();
System.out.println("BufferedReader/Writer + 버퍼 사용");
char [] buf = new char[1024]; // 버퍼 제공
int charsRead = 0;
charsCopied = 0;
startTime = System.currentTimeMillis();
while((charsRead = br.read(buf)) != -1) {
bw.write(buf, 0, charsRead);
charsCopied += charsRead;
}
fw.flush();
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
System.out.println("읽고 쓴 문자수: " + charsCopied);
System.out.println("경과시간(ms): " + elapsedTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
PrintWriter / 인코딩
java.lang.Object
└─ java.io.Writer
└─ java.io.PrintWriter
텍스트 파일 작성시는 PrintWriter 객체 편리
println(), print(), printf() ..
텍스트 파일 읽을시는 BufferedReader 객체 편리
read(), read(버퍼), readLine()..
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("파일명" 혹은 File)));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("파일명" 혹은 File))));
BufferedReader br = new BufferedReader(new FileReader("파일이름" 혹은 File));
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("파일이름" 혹은 File))));
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("파일이름" 혹은 File)));
★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
인코딩 문제
FIleReader, FileWriter 는 파일의 인코딩을 무조건 file.encoding 값으로 간주한다.
(ex: LINUX 는 UTF-8, MacOS 는 한글상위의 경우 euc-kr, 윈도우즈는 Java 소스코드 인코딩 영향)
인코딩 설정하기
InputStreamReader, OutputStreamWriter 를 사용해서 인코딩 변경을 해야 한다.
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("파일이름" 혹은 File),"인코딩"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("파일이름" 혹은 File), "인코딩"));
인코딩 : "UTF8", "euc-kr"
package com.lec.java.file13;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class File13Main {
private static final String FILE1 = "temp/PrintData.txt";
private static final String FILE2 = "temp/PrintData_euckr.txt";
public static void main(String[] args) {
System.out.println("PrintWriter / 인코딩 ");
FileWriter fw = null;
FileReader fr = null;
PrintWriter out = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
// fw = new FileWriter(FILE1);
// bw = new BufferedWriter(fw);
// out = new PrintWriter(bw);
out = new PrintWriter(new BufferedWriter(new FileWriter(FILE1)));
test_write(out);
System.out.println();
br = new BufferedReader(new FileReader(FILE1));
test_read(br);
out.close();
br.close();
System.out.println("현재 인코딩 " + System.getProperty("file.encoding"));
// euc-kr 로 인코딩하여 저장
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE2), "euc-kr")));
test_write(out);
System.out.println();
// 다른 인코딩으로 읽어오면 텍스트 깨진다
// br = new BufferedReader(new InputStreamReader(new FileInputStream(FILE2)));
// 원하는 인코딩으로 텍스트 읽기
br = new BufferedReader(new InputStreamReader(new FileInputStream(FILE2), "euc-kr"));
test_read(br);
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
try {
if(br != null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("\n프로그램 종료");
} // end main()
private static void test_read(BufferedReader br) throws IOException {
String line;
StringBuffer sb = new StringBuffer();
while((line = br.readLine()) != null) {
sb.append(line + "\n");
}
System.out.println(sb);
}
private static void test_write(PrintWriter out) {
out.println("안녕하세요 Java 한글이 잘 보이나요?");
out.print((2000 + 20) + " " + 3.14);
out.println();
out.printf("%d-%d-%d\n", 2020, 3, 2);
out.flush();
}
// TODO
} // end class