티스토리 뷰

( 이 블로그에서는 자바의 I/O에 대해서 깊게 다루지 않는다. 나중에 스프링부트를 공부할 때 이해할 수 있는 정도만 공부하는 것이 현재 목표이기에, 바이트 스트림, 출력 스트림의 클래스들의 메서드 등과 같은 내용은 다루지 않는다.) 

 

 

데이터는 키보드, 파일, 프로그램을 통해서 입력될 수 있고, 또 다른 파일, 프로그램으로 출력되거나 전송될 수 있다. 

이것을 총칭해서 데이터 입출력이라고 한다. 

 

🟩 스트림이란? 

자바는 입력 스트림과 출력 스트림을 통해 데이터를 입출력한다. 

이때 스트림이란, 단방향으로 데이터가 흐르는 것을 말한다. 

프로그램 기준으로 데이터가 들어오면 입력 스트림, 데이터가 나가면 출력 스트림이 된다. 

 

이때, 어떤 데이터를 입출력하느냐에 따라 스트림은 다음 두 종류로 구분할 수 있다. 

🟣 바이트 스트림 : 이미지, 비디오, 멀티미디어 등 모든 종류의 데이터(이진수)를 입출력할 때 사용. 
🟣 문자 스트림 : 문자만 입출력할 때 사용. 

 

바이트 입출력 스트림의 클래스, 문자 입출력 스트림의 클래스 각각 간단하게 살펴보고 가자. 

🔵 바이트 입출력 스트림의 최상위 클래스는 InputStreamOutputStream이다.

이 클래스를 상속 받는 하위 클래스에는 접미사로 InputStream 또는 OutputStream이 붙는다. 

🔵 문자 입출력 스트림의 최상위 클래스는 ReaderWriter이다. 

이 클래스를 상속받는 하위 클래스에는 접미사로 Reader 또는 Writer가 붙는다. 

 

(

이후, 

InputStream과 OutputStream, Reader와 Writer의 하위 클래스 종류 및 

바이트 출력, 바이트 배열 출력, 바이트 읽기, 바이트 배열로 읽기, 

문자 출력, 문자 읽기를 위한 주요 메서드를 사용, 또 그에 따른 활용은 정리하지 않겠다. 

)

 

🟩 보조 스트림 

보조 스트림이란, 다른 스트림과 연결되어 여러 가지 편리한 기능을 제공해주는 스트림을 말한다. 

보조 스트림은 자체적으로 입출력을 수행할 수 없기 때문에 입출력 소스로부터 직접 생성된 입출력 스트림에 연결해서 사용해야한다. 

 

자주사용되는 보조스트림의 예시로는, 

  • InputStreamReader : 바이트 스트림을 문자 스트림으로 변환 
  • BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter : 입출력 성능 향상 
  • ObjectInputStream, ObjectOutputStream : 객체 입출력 

등이 있다. 

 

🟩 성능 향상 스트림

CPU와 메모리가 아무리 뛰어나도 하드 디스크의 입출력이 늦어지면 프로그램의 실행 성능은 하드디스크의 처리 속도에 맟춰진다. 

이에 대한 완전한 해결책은 하니지만, 

프로그램이 입출력 소스와 직접 작업하지 않고, 중간에 메모리 버퍼(buffer)와 작업함으로써 실행 성능을 향상시킬 수 있다. 

 

출력 스트림의 경우, 직접 하드 디스크에 데이터를 보내지 않고 메모리 버퍼에 데이터를 보냄으로써 출력 속도를 향상시킬 수 있다

버퍼는 데이터가 쌓이기를 기다렸다가 꽉 차게 되면 데이터를 한꺼번에 하드 디스크로 보냄으로써 출력 횟수를 줄여준다

 

입력 스트림에서도 버퍼를 사용하면 읽기 성능이 좋아진다. 

하드 디스크로부터 직접 읽는 것보다는 메모리 버퍼로 부터 읽는 것이 빠르다.

 

( 왜 버퍼로 출력, 읽는 것이 효율적이고 빠른지는 다른 포스팅에서 다루겠다. )

 

이러한 메모리 버퍼를 제공하여 프로그램의 실행 성능을 향상시키는 보조 스트림이 바로 위해서 예시로 언급한

BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter이다. 

 

 

🟩 객체 스트림 (직렬화(Serialization), 역직렬화(deserialization)) 

자바의 메모리에 생성된 객체를 파일 또는 네트워크로 출력하기위해  바이트 형태변환하는 과정과 

입력받았거나 네트워크로 받은 바이트(원래는 객체)를 다시 객체로 변환하는 과정을 각각 

직렬화(Serialization), 역직렬화(Deserialization)라고 한다. 

 

간단하게 말해서, 

🟣 직렬화(Serialization) : 객체 --> 바이트 (객체의 필드값을 일려로 늘어선 바이트로 변경하는 과정
🟣 역직렬화(Deserialization) : 바이트 --> 객체 (반대로 직렬화된 바이트를 객체의 필드값으로 복원하는 과정) 

이에 위에서 말한 보조 스트림인 ObjectInputStream과 ObjectOutputStream은 객체를 입출력할 수 있는 보조 스트림이다. 

ObjectOutputStream은 바이트 출력 스트림과 연결되어 객체를 직렬화하고, 

ObjectInputStream은 바이트 입력 스트림과 연결되어 객체로 복원하는 역직렬화를 한다

 

 

🟩 Serializable 인터페이스 

자바는 Serializable 인터페이스를 구현한 클래스만 직렬화할 수 있도록 제한한다. 

Serializable 인터페이스는 멤버가 없는 빈 인터페이스이지만, 객체를 직렬화할 수 있다고 표시하는 역할을 한다. 

 

또 객체가 직렬화될 때 인스턴스 필드값은 직렬화 대상이지만, 

정적 필드값과 transient로 선언된 필드값은 직렬화에서 제외되므로 출력되지 않는다.

public class Tmp implements Serializable {
	public int field1; // field1 ~ field4 --> 직렬화됨.
    protected int field2;
    int field3;
    private int field4;
    
    public static int field5; // 정적 필드는 직렬화에서 제외
    transient int field6; // transient로 선언된 필드는 직렬화에서 제외
}

 

 

 

🟩 serialVersionUID 필드

직렬화할 때 사용된 클래스와 역직렬화할 때 사용된 클래스는 기본적으로 동일한 클래스여야한다. 

만약 클래스의 이름이 같더라도 클래스의 내용이 다르면 역직렬화에 실패한다. 

아래와 같은 경우이다. 

1번 코드의 Member 클래스로 생성한 객체를 직렬화하면, 2번 코드의 Member 클래스로 역직렬화할 수 없다. 

// 1번 코드
public class Member implements Serializable {
	int field1;
    int field2;
}
// 2번 코드
public class Member implements Serializable {
	int field1;
    int field2;
    int field3;
}

 

즉, 클래스 내용이 다르다 할지라도 직렬화된 플드를 공통으로 포함하고 있다면 역직렬화할 수 있는 방법이 있다. 

바로 두 클래스가 동일한 serialVersionUID 상수값을 가지고 있으면 된다

servialVersionUID란 쉽게 말해서 역직렬화하고자하는 클래스가 직열화한 클래스와 같은지 확인하는 기준이라고 생각하면 될 것같다.

아래처럼 말이다. 

// 1번 코드
public class Member implements Serializable {
	static final long serialVersionUID = 1;
	int field1;
    int field2;
}
// 2번 코드
public class Member implements Serializable {
	static final long serialVersionUID = 1;
	int field1;
    int field2;
    int field3;
}

 

serialVersionUID의 값은 개발자가 임의로 줄 수 있지만 가능하다면 클래스마다 다른 유일한 값을 갖도록 하는 것이 좋다. 

 

 

 

-------------------

체스 게임의 체크메이트 로직을 구현중이다... 다음은 서비스를 구현하고 실행 테스트를 해봐야겠지...

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함