Contents

조회 수 17134 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Java Input/Ouput Stream #3 (Object)

자바 입출력을 하다 보면 파일을 저장에서 한가지 궁금점이 생기게 됩니다. 
"PC게임에서 사용 되는 저장 기법은 무엇인가?" 라는 생각을 하게 됩니다.

단순히 String, int, long 등의 변수값을 텍스트 형식 또는 바이너리 형식으로 저장하는 형식인가?

그럼 바이너리 형식으로 저장한다면 어떻게 변수 값을 바이너리로 저장해야 하는 것인가?


이런 의문을 갖게 됩니다.
이 궁금증의 해답을 찾으려면 바이트스트림 계층도를 참고 하는 것이 기본적인 힌트 입니다.

보통 입출력 스트림을 이용할 떄는 버퍼라는 것을 달아주는 경우가 있습니다.
이 경우에는 버퍼를 사용하지 않을 때 보다 더 수월한 동작을 보여준다고 합니다.

그래서 블로그에 소개된 입출력 예제를 보면 입출력에 상당히 긴 문장을 갖추고 있습니다.
그렇다면 당연히 각 입출력 스트림 계층도에서 각 클래스들이 무엇인지 파악할 수 있습니다.

그런데 바이트 스트림에서 좀 특이하게 존재하는 것이 있습니다.
Object 단어로 시작하는 ObjectInputStream과 ObjectOutputStream 입니다.

이 두 클래스는 바이트스트림 이면서도 재미난 특징을 갖고 있어서 오브젝트 스트림이라고도 합니다.
간략한 설명을 하자면 오브젝트를 입출력 하기 위한 스트림이기 때문에 객체를 입출력합니다.

지금 까지 입출력 스트림을 보면 "텍스트를 저장한다.", "바이너리 파일을 복사한다." 라고만 생각하게 됐습니다.
그런데 사실은 이 모든 행위가 오브젝트 스트림이라고 할 수 있습니다.

파일을 불러오는 행위를 잘 생각해 봅시다.
실제로 파일을 가져 오는 것이 아니라 File 클래스의 객체 통해서 가져오게 됩니다. 
반대로 텍스트를 저장할 때도 마찬가지 입니다.
텍스트를 저장하는 것이 아니라 String 클래스의 객체를 저장하는 것 입니다.

그렇다면 "개발자가 만든 클래스를 저장할 수 있지 않을까?" 라는 생각도 충분히 할 수 있습니다.
그런데 그런 의심만으로 개발자가 제작한 클래스의 객체를 저장하려고 시도를 하면 저장은 커녕 에러 메시지가 출력되게 됩니다.

무엇인가 2%가 모자르게 되는 것이지요.
여기서 한가지 알아야 할 것이 있습니다.
입출력을 할 수 있는 클래스는 전부 직렬화가 구현이 돼 있어야 한다는 것 입니다.

직렬화는 자바에서 제공하는 클래스들은 대부분 구현이 돼 있습니다.
확인 방법은 자바 API 문서를 이용해서 String 클래스를 확인해 보면 Serializable 인터페이스가 구현 돼 있다고 확인 할 수 있습니다.

실제로 Serializable 인터페이스는 아무 내용도 없는 인터페이스 입니다.
그러나 이 인터페이스를 구현(implements Serializable) 하게 되면 오브젝트 스트림을 비롯한 모든 입출력 스트림을 사용할 수 있게 됩니다.

쉽게 말해 Serializable 인터페이스를 구현이 직렬화를 하는 것 입니다.
직렬화를 하게 되면 여러가지로 좋은 이점이 나오는데 만약 네트워크 프로그래밍을 하는 경우에 직렬화를 하지 못한다면 여러가지 정보를 전달 할 떄 번거로운 코딩 작업을 해야 합니다.
종류가 10개 정도 되는 String, int, long, byte 정보를 전송한다고 생각 하면 일일이 전송을 하도록 출력에 해당하는 코딩을 해줘야 합니다.

그러나 여기에 자료형 클래스를 직렬화 시켜서 네트워크 목적지로 출력 스트림을 만들어 준다면 효율은 아주 좋아집니다. 그리고 처음에 생각 했던 게임에서의 저장 방식을 만들 수 있게 됩니다. 

보통 RPG 게임을 하게 되면 현재 까지 진행한 부분까지 저장을 하고 로드를 하면 그 지점까지 불러와 지게 됩니다.
보통 파일을 저장하는 것은 케릭터 정보와 시나리오 정보를 저장하는 것입니다.
시나리오 정보와 케릭터 정보를 하나의 클래스로 묶어 저장을 한다면 불러올 떄도 아주 쉽습니다.

그럼 간단한 직렬화 예제를 보도록 합시다.
import java.io.*;

class A{
    public static void main(String args[]) {
        SaveFile file = new SaveFile();
        file.str = "직렬화";
  
        try{
            ObjectOutputStream oos =
                new ObjectOutputStream(new FileOutputStream("SaveFile"));
            oos.writeObject(file);
            oos.flush();
   
            ObjectInputStream ois =
                new ObjectInputStream(new FileInputStream("SaveFile"));
            SaveFile file2 = (SaveFile) ois.readObject();
   
            ois.close();
            oos.close();
   
            file2.print();
   
        }catch(Exception e){}
    }
}

class SaveFile implements Serializable{
    String str;
 
    public void print(){
        System.out.println(str);
    }
}

위 예제를 보면 SaveFile 클래스는 직렬화 하지 않으면 저장 및 읽기가 불가능합니다.
그러나 직렬화를 구현함으로써 오브젝트 스트림을 이용해서 저장과 불러오기를 할 수 있습니다.

사용 방법은 기존의 입출력 스트림과 큰 차이는 없지만 주의해야 할 점은 여기도 존재합니다.

직렬화 된 클래스는 조금이라도 편집 되면 편집 이전에 저장된 클래스 파일은 읽어 올 수 없습니다.
(가끔 게임 버전을 업그레이드 하면 세이브 파일 호환 되지 않는 것이 아마 이 문제와 관련 된 것으로 예상 됩니다.)
오브젝트 스트림을 이용해서 읽기를 하는 경우에 읽어 오게 되는 객체는 최상위 클래스인 Object 클래스형이므로 캐스팅을 해야 합니다.
개발자가 만든 클래스는 당연히 존재해야 합니다.
그래야 해당 클래스로 저장한 파일을 읽어 올 수 있습니다.

위 예제는 아주 기본적인 예제 입니다.
연습을 많이 해보시길 바랍니다.
특히 오브젝트 스트림은 입출력 스트림 중에서도 가장 흥미로운 부분이 아닐까 합니다.

이렇게 직렬화 된 객체를 저장 한 뒤에 울트라에디트 같은 바이너리 파일 편집기를 이용해 열어 보면 일부 코드를 수정함으로 실제 파일 내용이 수정 되는 것도 볼 수 있습니다.
(간혹 데이터 파일에 CheckSum 비트를 추가해 암호화 같은 기법을 사용 하는 경우가 있는데 이런 경우에는 데이터 수정이 쉽지는 않습니다.)

직렬화에 관한 공부를 별도로 하지 않아서 자세한 것은 알지 못하지만 직렬화는 데이터의 입출력 방식을 일정한 규칙을 이용해 입출력의 호환성이나 여러가지 효율을 향상 시키는 것으로 예상 됩니다.

감사합니다.

TAG •

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
1173 Develop '2014 모바일 개발 트렌드' 발표자료입니다. file hooni 2014.10.02 976
1172 System/OS Apache CORS 설정 1 hooni 2020.09.04 2708
1171 Develop Aspect Oriented Programming in Objective-C hooni 2015.05.18 674
1170 System/OS asx미디어 정보 기록.. hooni 2003.04.23 20533
1169 System/OS CentOS 6.5 USB 설치 6 file hooni 2013.12.18 37674
1168 System/OS CentOS 에서 Cacti 설치하기 hooni 2015.01.02 1760
1167 System/OS Configure Postfix to Use Gmail SMTP on Ubuntu 18.04 file hooni 2020.02.07 1244
1166 Develop DDay Memo 1.9.4 소스코드 secret hooni 2015.10.03 0
1165 Etc EBS [수학영역] 미적분과 통계 기본 - 정규분포의 의미와 특징은? hooni 2015.04.20 1001
1164 System/OS Enable Safari Hidden Debug Menu in Mac OS X file hooni 2017.02.07 1140
1163 System/OS Enable the Develop Menu in Safari file hooni 2017.02.07 1067
1162 Develop GCM 사용하기 2 (단말에 GCM 구현하기) file hooni 2013.07.06 23248
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 98 Next
/ 98