Java

고수준 스트림(Data/Object Stream)

ryeonng 2024. 6. 3. 17:18

DataInputStream 과 DataOutputStream

DataInputStreamDataOutputStream은 자바의 I/O 스트림 클래스 중 하나로, 원시 자료형(정수, 실수, 문자 등)을 쉽게 읽고 쓸 수 있도록 도와준다.
이 두 클래스는 데이터의 형식을 유지하면서 입력 및 출력을 수행할 수 있어, 자료의 손실 없이 데이터를 주고 받을 수 있다.

 

package io.file.ch08;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class MyDataStream {

	public static void main(String[] args) {

		// 데이터 쓰기 - 바이트, 문자 기반이 아닌 기본 자료형 데이터 타입으로 보내기
		// 파일에다 사용 -> FileOutPutStream("대상 파일 이름") <- 확장(보조 스트림-DataOutputStream) 
		try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("student.txt"))) {
			dos.writeInt(101); // 학번
			dos.writeUTF("홍길동"); // 이름
			dos.writeDouble(3.5); // 학점
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println(">>> 데이터 쓰기 완료 (원시타입) <<<");
		
		// 기본 데이터 타입으로 데이터 읽기
		try (DataInputStream dis = new DataInputStream(new FileInputStream("student.txt"))) {
			int id = dis.readInt();
			String name = dis.readUTF();
			double score = dis.readDouble();
			
			System.out.println("학번 : " + id);
			System.out.println("이름 : " + name);
			System.out.println("학점 : " + score);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println(">>> 데이터 읽기 완료 (기본 데이터 타입) <<<");
		
	} // end of main

} // end of class

 


ObjectInputStream과 ObjectOutputStream, 그리고 직렬화

ObjectInputStreamObjectOutputStream은 객체를 직렬화하여 파일에 쓰거나 네트워크로 전송하고, 이를 다시 역직렬화하여 객체로 복원할 때 사용하는 자바의 I/O 클래스이다.

  • 직렬화(Serialization) : 객체의 상태를 바이트 스트림으로 변환하여 파일에 저장하거나  네트워크를 통해 전송할 수 있게 하는 과정
  • 역직렬화(Deserialization) : 바이트 스트림으로부터 객체를 복원하는 과정
직렬화(Serialization)에서 "바이트 스트림으로 변환한다"는 것은 객체의 상태(필드 값 등)를 바이트 단위의 데이터로 변환하고, 이를 스트림을 통해 입출력(I/O) 작업을 수행할 수 있도록 하는 과정이다.

 

package io.file.ch08;

import java.io.Serializable;
/**
 * 특정 클래스를 직렬화 하기 위해서는 상위 부모 또는 바로 Serializable 를 구현 해야 한다.
 */
public class Person implements Serializable{

	private static final long  serialVersionUID = 1L; // 직렬화 버전 UID (클래스의 버전 관리를 위해 사용되는 고유 식별자)
	private String name;
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name =" + name + ", age=" + age + "]";
	}
}

 

Serializable 인터페이스를 구현하는 이유?

Serializable 인터페이스는 마커 인터페이스로, 이 인터페이스를 구현하는 클래스는 직렬화할 수 있다는 의도를 명확히 한다.

자바 런타임 환경(JRE)에 해당 객체가 직렬화 및 역직렬화에 적합함을 알려준다.

 

serialVersionUID 사용 이유?

SerialVersionUID는 클래스의 버전 관리를 위해 사용되는 고유 식별자이다.

직렬화 된 객체를 역직렬화할 때, 저장된 객체의 serialVersionUID와 클래스의 serialVersionUID가 일치하는지 검사하여, 객체의 호환성을 확인한다.

  • 버전 관리 : 클래스가 변경되면 (예 : 필드 추가, 메서드 변경 등), 기존에 직렬화 된 객체와 호환성을 유지하기 위해 serialVersionUID를 명시적으로 정의한다.
  • 자동 생성 : serialVersionUID 를 명시하지 않으면 자바 컴파일러가 자동으로 생성하지만, 이는 클래스의 변경에 따라 달라질 수 있어 명시적으로 정의하는 것이 좋다. 
package io.file.ch08;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class MyObjectStream {

	public static void main(String[] args) {

		// 객체 직렬화
		try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"))) {
			
			Person person = new Person("손흥민", 30);
			oos.writeObject(person);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("--------------------------------------");
		
		// 객체 역직렬화
		try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
			
			// 문자 기반으로 데이터를 읽으면, 스트링 값 추출해 코드 상에 활용할 수 있도록 object 만드는 과정 코딩필요.
			// name:, 10 <-
			Person person = (Person)ois.readObject(); // 다운캐스팅
			System.out.println(person);
			
		} catch (Exception e) {
			e.printStackTrace(); // 예외 처리 흐름 생성 가능 
		}
		
	} // end of main

} // end of class

'Java' 카테고리의 다른 글

1:1 단방향 통신 (서버측)  (0) 2024.06.12
Socket  (1) 2024.06.12
사용자모드와 커널모드  (4) 2024.05.31
파일 출력 스트림(문자 기반 스트림)  (0) 2024.05.31
파일 출력 스트림(바이트 기반)  (2) 2024.05.23