티스토리 뷰

자바는 file에 객체단위로 wirte,read하는것을 허용한다.

객체단위로 파일에 쓰거나 읽을 때는 맞는 스트림을 만들어서 사용하면 된다.

 

ObjectInputStream/ObjectOutputStream

코드 예제를 통해서 알아보자

 

public void saveList(TodoList vo) {

//try~catch resource로 사용
//FileOuputStrema("filename",true) 의 경우 파일이 존재하면 덮어쓰는게 아니라
//추가의 용도로 사용할 수 있게됨.
		try (FileOutputStream fos = new FileOutputStream("data.dat",true);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
				ObjectOutputStream oos = new ObjectOutputStream(bos);) {
			oos.writeObject(vo);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	public ArrayList<TodoList> loadList(){
		
		ArrayList<TodoList> list = new ArrayList<TodoList>();
		try(FileInputStream fis = new FileInputStream("todolist.dat");
				BufferedInputStream bis = new BufferedInputStream(fis);
				
				){
			while(true) {
            //이줄이 에러의 포인트이다.
				ObjectInputStream ois = new ObjectInputStream(bis);
				TodoList t = (TodoList) ois.readObject();
				System.out.println(t);
				list.add(t);
			}
			
		}catch(EOFException e){
			
		}
		catch(IOException | ClassNotFoundException e){
			e.printStackTrace();
		}
		catch(NullPointerException e){
			
		}
		return list;
	}

위의 코드는 객체를 파일의 쓰고 읽는 코드이다 여기서 잠깐! 객체단위 스트림을 사용하기 위해서는 해당 클래스의 직렬화가 필요하다 jvm에서는 직렬화-역직렬화를 통해 객체 단위로 스트림을 읽기 때문!

 

class className implements Serializable{}을 통해 선언이 가능하다.

 

그렇다면 java.io.StreamCorruptedException은 왜 발생하게 되는가??

 

1.stream의 경우 쓰는것과 읽는것의 형식이 같아야한다 

output.writeObject(date) 의 경우로 쓰면 input.readObject()로 읽어야 된다는사실!

 

2.한번에 객체를 write하는게 아닌 동적으로 파일에 계속 update할 경우 객체의 스트림 헤더가 바뀌게 된다.

이때 에러가 나는 부분이 위의 코드에서 표시해둔 부분! 에러포인트 이 부분을 잘 살펴보면 ObjectInputStream이 객체를 읽을때마다 새로 생성하는것을 알 수 있다. 하나의 ObjectOutputStream으로 write한게 아니라 읽을때도 따로따로 읽을 수 있게 Stream을 객체마다 새로 생성해줘야 한다는 사실!

 

만약 클래스의 직렬화선언도 되어있고 1번의 경우도 아니라면 2번의 경우에서 에러가 날 가능성이 크다!

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함