15장

1. Stream

  • I/O(Input/Output): 내부 또는 외부의 장치와 프로그램 간의 데이터를 주고받는 것

  • 스트림(stream): 두 대상을 연결하고 데이터를 전송하는데 시용하는 연결 통로

    • 14장의 데이터 소스를 추상화하고 다루는 스트림과 별개임에 유의

    • 스트림은 단방향 통신만 가능

    • 스트림은 먼저 보낸 데이터를 먼저 받게 되어있음

  • 보조 스트림: 스트림의 기능을 보완하기 위한 스트림

    • 실제로 데이터를 주고받는 스트림이 아니므로 데이터 입출력 기능은 없음

    • 기반 스트림을 생성한 후 기반 스트림을 이용해서 보조 스트림 생성

1.1. 바이트 기반 스트림

입력 스트림
출력 스트림
입출력 대상의 종류

FileInputStream

FileOutputStream

파일

ByteArrayInputStream

ByteArrayOutputStream

메모리(byte 배열)

PipedInputStream

PipedOutputStream

프로세스(프로세스 간 통신)

AudioInputStream

AudioOutputStream

오디오 장치

1.2. 문자 기반 스트림

입력 스트림
출력 스트림
입출력 대상의 종류

FileInputReader

FileOutputWriter

파일

ByteArrayInputReader

ByteArrayOutputWriter

메모리(byte 배열)

PipedInputReader

PipedOutputWriter

프로세스(프로세스 간 통신)

AudioInputReader

AudioOutputWriter

오디오 장치

1.3. 보조 스트림

입력
출력
설명

FilterInputStream

FilterOutputStream

필터를 이용한 입출력 처리

BufferedInputStream

BufferedOutputStream

버퍼를 이용한 입출력 성능 향상

DataInputStream

DataOutputStream

int, float와 같은 기본형 단위로 데이터 처리

SequenceInputStream

-

두 개의 스트림을 하나로 연결

LineNumberInputStream

-

읽어 온 데이터의 라인 번호를 키운트 (JDK 1.1부터 LineNumberReader로 대체)

ObjectInputStream

ObjectOutputStream

데이터를 객체 단위로 읽고 쓰는데 사용 주로 파일을 이용하며 객체 직렬화와 연관

-

PrintStream

버퍼를 이용하며 추가적인 print 관련 기능 (print, printf, println 메서드)

pushbackInputStream

-

버퍼를 이용해서 읽어 온 데이터를 다시 되돌림 (unread)

2. 직렬화

2.1. 직렬화와 역직렬화

  • 직렬화(serialization): 객체를 데이터 스트림으로 만드는 것

  • 역직렬화(deserialization): 데이터 스트림에서 객체를 만드는 것

png

2.2. 직렬화와 역직렬화의 예시

/*
==========================================================================
1. 직렬화
==========================================================================
*/
// FileOutputStream 사용
FileOutputStream fos = new FileOutputStream("log.txt");
ObjectOutputStream out = new ObjectOutputStream(fos);

out. writeObject(new UserInfo());

// 메서드 직접 구현
private void writeObject(ObjectOutputStream out) 
	throws IOException {
	// write 메서드를 사용해서 직렬화 수행
}

/*
==========================================================================
2. 역직렬화
==========================================================================
*/
// FileInputStream 사용
FileInputStream fis = new FileInputStream("log.txt");
ObjectInputStream in = new ObjectInputStream(fis);

UserInfo info = (UserInfo)in.readObject();

// 메서드 직접 구현
private void readObject(ObjectInputStream in) 
	throws IOException, ClassNotFoundException {
    // read 메서드를 사용해서 역직렬화 수행
}

/*
==========================================================================
3. 직렬화 가능한 클래스 만들기 - Serializable
- 조상 클래스가 Serializable을 구현한 경우 자손도 직렬화 가능
- 조상 클래스가 구현하지 않은 경우 자손 클래스를 직렬화 했을 때 조상 클래스 변수 제외
==========================================================================
*/
// 일반적인 클래스
public class UserInfo {
	String name;
    String password;
    int age;
}

// 직렬화 가능한 클래스
public class UserInfo 
	implements java.io.Serializable { // Serializable 인터페이스 구현
	String name;
    String password;
    int age;
}

/*
==========================================================================
4. 직렬화 대상에서 제외 - transient
==========================================================================
*/
// 직렬화 가능한 클래스
public class UserInfo implements Serializable {
	String name;
    String password;
    int age;
    Object obj = new Object(); // 직렬화 불가
    Object obj2 = new String("abc"); // 직렬화 가능
}

// 직렬화 대상에서 제외
public class UserInfo implements Serializable {
	String name;
    transient String password;
    int age;
    transient Object obj = new Object(); // 직렬화 불가
    Object obj2 = new String("abc"); // 직렬화 가능
}

참고 자료

  • 자바의 정석 - 도우출판

Last updated