1. 성능 향상
BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter 등이 해당된다.2. 기능 추가
DataInputStream 및 DataOutputStream은 기본 자료형을 바로 읽거나 쓸 수 있는 메소드 제공ObjectInputStream 및 ObjectOutputStream은 객체 직렬화를 지원하여 객체를 파일에 쓰거나 읽을 수 있음3. 편리한 메소드 제공
PrintWriter는 문자열을 쓰거나 println 메소드를 통해 자동으로 개행 추가4. 코드 간결성
BufferedOutputStream은 내부적으로 데이터를 메모리에 버퍼링하고, 버퍼가 가득차거나 flush() 메소드가 호출될 때만 실제로 파일에 데이터를 쓰기 때문에 입출력 성능이 향상된다.try {
FileOutputStream fos = new FileOutputStream("d:/d_other/bufferTest.txt");
// 버퍼 크기가 5byte인 버퍼 스트림 객체 생성
BufferedOutputStream bos = new BufferedOutputStream(fos, 5);
for(char c='1'; c<='9'; c++) {
bos.write(c);
}
// 출력 작업이 완료되면 출력 버퍼에 남아있는 데이터 강제 출력
// bos.flush(); -> 얘 안 하면 5까지 출력
// 보조 스트림을 닫으면 기반이 되는 스트림도 같이 닫힌다
// 버퍼 스트림의 close()에는 flush() 기능이 내장되어 있다
// fos.close();
bos.close();
System.out.println("작업 끝~~");
} catch (IOException e) {}
try {
// 자료 읽을시 줄 단위로 읽을 수 있음
FileReader fr = new FileReader("./src/kr/or/ddit/basic/FileTest01.Java"); // 해당 경로에 있는 자바 파일
BufferedReader br = new BufferedReader(fr);
String temp = "";
for(int i=1; (temp = br.readLine()) != null; i++) {
System.out.printf("%4d : %s\n", i, temp);
}
br.close();
} catch (IOException e) {}
- 데이터를 기본형 단위로 읽고 쓰는 보조스트림
- 메소드 💁♀️
readInt(), readByte(), readChar()..
- 8개의 기본 타입에 맞춰진 메소드
- 각 자료형에 맞는 값들을 읽어옴
- ex) int, long, short 입력시 내가 저장한 순서 4byte, 8byte, 2byte로 읽어야 함
String readUTF(): UTF 형식으로 쓰여진 문자를 읽음writeInt(), writeByte(), writeChar()..
- 8개의 기본 타입에 맞춰진 메소드
- 각 자료형에 맞는 값들을 출력
void writeUTF(String s): UTF 형식으로 문자 출력
// DataIOTest01.Java, DataIOTest02.Java
package kr.or.ddit.basic;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataIOTest01 {
public static void main(String[] args) {
try {
// 파일 저장하기 위한 기반 스트림
FileOutputStream fout = new FileOutputStream("d:/d_other/test.dat");
// 자료형 단위로 출력할 보조 스트림 객체 생성
DataOutputStream dout = new DataOutputStream(fout);
// 출력
dout.writeInt(200);
dout.writeFloat(123.45f);
dout.writeBoolean(false);
dout.writeUTF("ABCDabcd");
System.out.println("출력 완료!!");
dout.close();
} catch (IOException e) {}
}
}
// -------------------------------------------------------
package kr.or.ddit.basic;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class DataIOTest02 {
public static void main(String[] args) {
try {
// DataOutputStream으로 출력했던 데이터 읽어오기
FileInputStream fin = new FileInputStream("d:/d_other/test.dat");
DataInputStream din = new DataInputStream(fin);
// 출력 순서와 같은 순서로 읽기
System.out.println("정수형: " + din.readInt());
System.out.println("실수형: " + din.readFloat());
System.out.println("논리형: " + din.readBoolean());
System.out.println("문자열: " + din.readUTF());
System.out.println("\n읽기 작업 끝!!");
din.close();
} catch (IOException e) {}
}
}
- 객체를 직렬화하여 입출력할 수 있게 해주는 보조 스트림
- 직렬화란? 객체의 멤버 변수를 연속적인 데이터로 변환하는 것이다.
Serializable인터페이스를 구현해야 객체를 직렬화할 수 있음- 구현 안 하면 예외 → NotSerializableException
Serializable인터페이스는 구현해야 할 메소드는 없다. 직렬화 하겠다는 표시임- 직렬화된 데이터를 생성하거나 읽어들일 수 있게 됨
- 직렬화 제외 대상
transient가 붙은 인스턴스는 직렬화 대상에서 제외Serializable을 구현하지 않은 클래스의 인스턴스도 직렬화 대상에서 제외- 자식 객체가
Serializable인터페이스를 구현하더라도, 부모 객체가Serializable을 구현하지 않은 경우, 부모 클래스의 멤버 변수는 자동으로 직렬화 대상에서 제외
// ObjectIOTest.Java
package kr.or.ddit.basic;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectIOTest {
public static void main(String[] args) {
Member mem1 = new Member("홍길동", 20, "대전");
Member mem2 = new Member("홍길서", 30, "서울");
Member mem3 = new Member("홍길남", 40, "인천");
Member mem4 = new Member("홍길북", 50, "천안");
try {
// 객체를 파일에 저장하기
// 주로 처리할 보조 스트림을 마지막에 하는 게 좋당
FileOutputStream fout = new FileOutputStream("d:/d_other/memObj.dat");
BufferedOutputStream bout = new BufferedOutputStream(fout);
ObjectOutputStream oout = new ObjectOutputStream(bout);
// 저장 작업 (쓰기 작업)
oout.writeObject(mem1);
oout.writeObject(mem2);
oout.writeObject(mem3);
oout.writeObject(mem4);
oout.writeObject(null); // EOFException 방지하기
System.out.println("객체 저장 작업 끝!!");
oout.close();
} catch (IOException e) {
e.printStackTrace();
}
// ---------------------------------------------------------------------------
// 저장된 객체를 읽어와 그 객체의 내용을 화면에 출력
try {
ObjectInputStream oin = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("d:/d_other/memObj.dat")));
Object obj;
System.out.println("객체 읽기 작업 시작..\n");
System.out.println("------------------");
// readObject(): 데이터를 끝까지 다 읽어오면 EOFException을 발생시킴
while((obj = oin.readObject()) != null) {
// 읽어온 데이터를 원래 자료형으로 형변환 후 사용
Member mem = (Member)obj;
System.out.println("이름: " + mem.getName());
System.out.println("나이: " + mem.getAge());
System.out.println("주소: " + mem.getAddr());
System.out.println("------------------");
}
oin.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Member implements Serializable {
// transient: 직렬화 되지 않을 멤버변수 지정
private String name;
private transient int age; // 나이가 0으로 출력
private transient String addr;
public Member(String name, int age, String addr) {
super();
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}