복습

자바 17일차 - 직렬화, 나머지 입출력클래스, HEX코드 불러오기 본문

자바

자바 17일차 - 직렬화, 나머지 입출력클래스, HEX코드 불러오기

ykm1256 2020. 4. 9. 17:31

직렬화

: 인스턴스 변수 값은 계속 변하는데 어느 순간 상태를 그대로 저장하거나 네트워크를 통해 전송할 일이 있을 수 있다. 이를 직렬화라고 한다. 그리고 저장된 내용이나 전송받은 내용을 다시 복원하는 것을 역직렬화라고 한다. 즉 직렬화는 인스턴스 내용을 연속 스트림으로 만드는 것으로, 스트림으로 만들어야 파일에 쓰거나 네트워크로 전송이 가능하다.

 

ObjectInputStream() : InputStream을 생성자의 매개변수로 받아 ObjectInputStream을 생성한다.

ObjectOutputStream() : OutputStream을 생성자의 매개변수로 받아 ObjectOutputStream을 생성한다.

 

직렬화 예제

먼저 Serializable 인터페이스를 구현하는 Person 클래스를 만든다. 여기서 Person클래스는 이름과 직업을 받아오는 생성자를 만들고, toString()메서드를 재정의하여 이름과 직업을 출력하도록한다.

그리고 메인 함수에서 Person형 객체를 만들어 이름과 직업을 입력한다. 그 다음 try-with-resource문으로 FileOutputStream을 생성하여 serial.out 파일을 만들고 그것을 ObjectOutputStream으로 받아온다. 그리고 writeObject()메서드로 각각의 이름과 직업을 받아서 파일에 저장한다. 그 다음 try-with-resource문으로 FileInputStream으로 serial.out 파일을 열도록 스트림을 생성하고, 그 참조변수를 ObjectInputStream으로 받는다. 그리고 Person 형 객체를 만들어 readObject()메서드로 파일에서 받아온 값을 대입한다. 그리고 각각을 출력한다.

*10행에서 Serializable 인터페이스를 구현해주었는데 이를 하지 않으면 위의 사진처럼 오류가 발생한다.

 

trasient 예약어

: 직렬화 될 수 없거나, 직렬화하고 싶지 않을 때 사용하는 예약어

위의 코드처럼 앞에 transient를 써주면 직렬화 되지않아 null값이 출력된다.

 

File 클래스

: 별도의 입출력 기능은 없지만 파일 자체의 경로나 정보를 알 수 있고, 파일을 생성할 수 있는 클래스

9행에서 설정해준 경로에 File 클래스를 생성했다.(아직 파일이 생성되지 않음) 그리고 10행에서 파일을 생성하고, 여러가지 메서드를 사용하여 차례대로 파일인지, 디렉토리인지를 출력했다. 그리고 파일이름, 전체경로, 경로, 읽을 수 있는 지, 쓸 수 있는 지를 출력했다.

 

 

이 코드는 list() 메서드를 추가하여 파일이 있는 경로에 있는 폴더나 파일의 목록을 출력하였다.

 

RandomAccessFile 클래스

: 유일하게 파일 입출력을 동시에 할 수 있는 클래스

10행에서 RandomAccessFile 클래스를 생성하고 파일 이름과 기능을 설정했다. rw는 읽고 쓰기 기능이며, r을 쓰면 읽기 전용 기능이다. 그리고 각각 100, 3.14, "안녕하세요"를 파일에 입력했다. 여기서 포인터 위치를 보면 값을 입력할 때마다 포인터 위치가 증가하여 이동한다. 즉, 파일포인터가 계속 이동하면서 파일을 읽거나 쓰게 된다. 따라서 18~20행에서 변수를 선언하고 값을 대입한 후 출력하려고 하면 포인터는 이미 가장 뒤에있는데 그전에 사용한 위치의 값을 불러오려고 하여 에러가 발생했다.

 

따라서 위의 코드처럼 seek()메서드로 포인터의 위치를 처음 위치인 0으로 재설정 하고 다시 변수에 대입하여 출력하면 정상적으로 출력된다.

*값을 불러올 때는 저장한 자료형에 맞게 불러와야 한다.

 

파일의 hex값을 정렬하여 출력해주는 프로그램 구현하기

위의 사진은 Visual Studio Code 프로그램을 이용하여 serial.out 이라는 파일을 hexdump로 읽어 온 것이다.

이클립스를 활용하여 위의 형식으로 출력되도록 구현하였다.

 

먼저 printTitle() 메서드에서 hex코드가 출력되기 전에 타이틀로 출력될 코드를 구현했다. 그리고 readNPrint() 메서드를 만들어 파일을 받아서 형식에 맞게 hex코드로 출력하였다. 책에서 한 것과 같이 FileInputStream을 이용하여 serial.out 파일을 읽어온다. 그리고 16개씩 출력해야 하므로 크기가 16인 배열을 만든다. 그리고