2011-12-08 6 views
0

기본 저장/열기 기능을 가진 Java 응용 프로그램을 만들고 있습니다. 저장해야하는 것은 클래스의 인스턴스입니다. ModeleImage 이것은 싱글 톤입니다. 저의 저축은 다음과 같이 작동합니다 :기존 Singleton 객체를 ObjectInputStream을 사용하여 저장된 파일로 대체하는 방법은 무엇입니까?

ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file)); 
outputStream.writeObject(ModeleImage.getInstance()); 
outputStream.flush(); 
outputStream.close(); 

이제 ObjectInputStream으로 해당 파일을 열려고합니다. 나는 이미 싱글 톤 (ModeleImage)를 저장된 파일로 대체하는 방법이 있는지 모르겠지만, 지금은 각 속성을 복사하고 대체하려고합니다. 내 개방은 다음과 같습니다

FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile()); 
ObjectInputStream ois = new ObjectInputStream(fis); 

//Get each attribute from the file and set them in my existing ModeleImage Singleton 

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage()); 
ModeleImage.getInstance().setLargeurImage(((ModeleImage) ois.readObject()).getLargeurImage()); 
ModeleImage.getInstance().setHauteurImage(((ModeleImage) ois.readObject()).getHauteurImage()); 
ModeleImage.getInstance().setxImage(((ModeleImage) ois.readObject()).getxImage()); 
ModeleImage.getInstance().setyImage(((ModeleImage) ois.readObject()).getyImage()); 

는 또한 각 주위에/시도 잡아 넣어. 문제는 애트리뷰트를 대체하려고 할 때 내 오프닝 파트가 IOException을 잡는다는 것이다.

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage()); 
//This catches an IOException 

내가 뭘 잘못하고 있니? 그것은 Singleton이거나 ObjectInputStream 및 readObject()가 어떻게 작동하는지 오해하기 때문입니까?

+0

편집 : 실제로 방금 저장을 시도 할 때 직렬화가 작동하지 않는다는 것을 알았습니다. 내가 저장 한 파일을 텍스트 편집기로 열려고 시도한 후 다음과 같이 시작합니다 : 'java.io.NotSerializableException' – user1088509

+0

편집 2 : 내 ModeleImage 클래스에서 Serializable을 구현하는 것을 잊었습니다. 이제 저장된 파일에는 오류가 없지만 작은 (205 바이트) 필드의 이름은 있지만 값은 포함하지 않습니다. 필드 중 하나는 이미지이므로 파일은 꽤 커야합니다. – user1088509

답변

1

직렬화 메커니즘의 기본 제공 기능을 사용하면 클래스 파일 내에 두 가지 방법을 제공하여 일반 프로세스를 향상시킬 수 있습니다. 그 방법은 다음과 같습니다

private void writeObject(ObjectOutputStream out) throws IOException; 
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; 

는 ModeleImage 클래스에 의해이 방법을 구현하고 직렬화의 모든 측면을 제어하고 싱글의 내부 상태에 액세스 할 수 있습니다.

ModeleImage image = ois.readObject(); 
ModeleImage.getInstance().setImage((image.getImage()); 
ModeleImage.getInstance().setLargeurImage(image.getLargeurImage()); 
ModeleImage.getInstance().setHauteurImage((image.getHauteurImage()); 
ModeleImage.getInstance().setxImage(image.getxImage()); 
ModeleImage.getInstance().setyImage(image.getyImage()); 
0

당신은 당신이 하나의 개체 만 썼다 번부터 readObject()를 호출해야합니다. 그것을 찾을 수 있다면, 그것을 싱글 톤 인스턴스에 설정합니다 (따라서 파일에서 파일을로드하도록합니다). 그것을 찾을 수 없다면 (아마도 프로그램이 처음 시작될 때), 인스턴스를 생성하고 이것을 singleton 변수에 할당해야합니다.

저장 방법을 만들거나 만들지 못하도록 할 수도 있고 finalize 메서드를 재정의하여 싱글 톤을 절약 할 수도 있습니다. 그러면 다음에 클래스가로드 될 때 정적 블록에서이를 확인할 수 있습니다.

의미가 있습니까?

+0

문제는 Singleton 인 ModeleImage의 새 인스턴스를 만들고 Singleton 패턴을 손상시키지 않으려 고합니다. – user1088509

+0

물론 이들 중 하나를 deserialize하여 Singleton 패턴을 깨고 있습니다. 그래서 여러분은 싱글 톤의 필드를 직렬화 된 객체의 필드로 업데이트하고 싶습니까? – Gray

+0

네, 그렇습니다. 하지만 방금 저축이 문제라고 알았습니다. 저장된 파일에'java.io.NotSerializableException' 오류가 발생합니다. – user1088509

0

당신이 할 일은 당신 직렬화 된 클래스의 인스턴스를 확인하는 정적 블록을 가지고 있습니다 :

+0

왜 내가 싱글 톤에 상태를 저장하고 싶은지 질문합니다. 그것은 매우 혼란 스러울 수 있습니다. 실제로 등록 정보 파일이나 다른 것을 사용하려고 할 수 있습니다. 아마도 상태를 저장하는 싱글 톤에 의해 관리되는 클래스가있을 것입니다. 그런 다음 싱글 톤을 직렬화하고 필요할 때 데이터를 한 번 가져올 수 있습니다. –

+0

저는 Java로 시작했는데 응용 프로그램에서 Singleton을 처음 사용했습니다. 분명히이 사람은 하나가되어서는 안되며 하나가 될 필요도 없으므로 나는 싱글 톤 패턴을 깨뜨리는 것에 신경 쓰지 않고, 모든 것을 다시 생각하지 않고 상태를 저장하기를 원합니다. 이제 내 문제는 내 ObjectOutputStream/ObjectInputStream 내 사용하는 것 같다. 직렬화에 대해서는 잘 모르기 때문에 도움이되지 않습니다. – user1088509

+0

글쎄,이 방법을 잘못 사용하지 마라.하지만 자바에서 배우는 사람이라면 디자인 패턴을 깨서는 안된다. 아무도 정말해야하지. 이것은 이유가되는 패턴입니다. 그것을 깨기 위해서는 디자인 패턴이라는 사실에서 벗어났습니다. 다시 말하지만, 잘못된 방향으로 생각하지 마십시오. 너를 돕기 위해 노력하고있어. –

0

private Object readResolve() throws ObjectStreamException 
{ 
    instance.setImage(getImage()); 
    instance.setLargeurImage(getLargeurImage()); 
    ... 
    return instance; 
} 

이 개념은 http://www.javalobby.org/java/forums/t17491.html에 잘 설명 또는 (가 readResolve에 대한 자세한 내용은 http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/input.doc6.html을 확인하는 하나의 인스턴스가 오직이 있는지 확인하고이 속성을 오버라이드 (override)하여 직렬화 싱글 톤 클래스에 readResolve에 구현). 희망이 도움이됩니다.