2016-04-13 8 views
1

thisObjectOutputStreamに書き込むことができない理由が不思議です。私は次のクラスを書かれて、それがすべての必要な輸入品と正常に動作することが分かってきたJavaでこれをシリアル化できないのはなぜですか

public class Cereal implements Serializable{ 

    private String name ; 
    private FileInputStream fis ; 
    private ObjectInputStream ois ; 
    private ObjectOutputStream oos; 
    private FileOutputStream fos ; 
    private Cereal readIn ; 
    private Cereal writeOut; 

    private Toy prize ; 
    public Cereal(String newName, String prizeName){ 
     name = newName ; 
    } 
    public String readBox(){ 
     return name ; 
    } 
    //Where it happens; unsuccessful line commented out 
    public void writeToFile(String arg) throws Exception{ 
     try{ 
      fos = new FileOutputStream(arg) ; 
      oos = new ObjectOutputStream(fos) ; 
      writeOut = new Cereal(name, prize.describe()); 
      oos.writeObject(writeOut); 
      //oos.writeObject(this); 
      oos.close(); 
      fos.close(); 
      System.out.println("wrote to " + arg); 

     }catch(Exception e){ 
      System.out.println("Problem"); 
      e.printStackTrace(); 
     } 

    } 
    public void writeToFile() throws Exception{ 
     // 
     writeToFile(name + ".ser") ; 
    } 
    public void readFromFile(String arg) throws Exception{ 

     try{ 
      fis = new FileInputStream(arg) ; 
      ois = new ObjectInputStream(fis) ; 

      System.out.println("Read from " + arg); 
      readIn = (Cereal) ois.readObject() ; 
      this.name = readIn.readBox(); 
      ois.close(); 
      fis.close(); 

     }catch(Exception e){ 
      System.out.println("Had a problem"); 
      e.printStackTrace(); 
     } 
    } 
    public void readFromFile() throws Exception{ 
     readFromFile(name + ".ser"); 
    } 


} 

はまだoos.writeObject(this)oos.writeObject(writeOut)を交換し、私は次のエラーを上げる:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.io.FileOutputStream 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1355) 
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2000) 
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1924) 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801) 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) 
    at Cereal.readFromFile(Cereal.java:56) 
    at MainDriver.main(MainDriver.java:13) 
Caused by: java.io.NotSerializableException: java.io.FileOutputStream 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
    at Cereal.writeToFile(Cereal.java:34) 
    at Cereal.writeToFile(Cereal.java:47) 
    at MainDriver.main(MainDriver.java:7) 

私はなぜこれが問題になるのかわからない、誰かがアイデアを持っている?前もって感謝します。 (私が今やっているとしてだけthisを使用するのではなく、属性を初期化するために面倒なようです。)

+1

ような何かFileInputクラスおよび出力ストリームは法の範囲内で開閉されます。それらはローカル変数でなければなりません。 – slipperyseal

答えて

3

と仮定ToySerializableである、あなたが(彼らSerializableではないので)transientあなたのストリームを作成する必要があります。何かのように、あなたのスタックトレースのルートが

Caused by: java.io.NotSerializableException: java.io.FileOutputStream 

あなたはまた、フィールドの代わりにそれらのストリームのローカル変数を作成し、クリーンアップするtry-with-resources Closeを使用することができますと言う理由です

private transient FileInputStream fis ; 
private transient ObjectInputStream ois ; 
private transient ObjectOutputStream oos; 
private transient FileOutputStream fos ; 

public void readFromFile(String arg) throws Exception { 
    try (ObjectInputStream ois = new ObjectInputStream(
       new FileInputStream(arg))) { 
     System.out.println("Read from " + arg); 
     readIn = (Cereal) ois.readObject(); 
     this.name = readIn.readBox(); 
    } catch (Exception e) { 
     System.out.println("Had a problem"); 
     e.printStackTrace(); 
    } 
} 

public void writeToFile(String arg) throws Exception { 
    try (ObjectOutputStream oos = new ObjectOutputStream(
       new FileOutputStream(arg))) { 
     writeOut = new Cereal(name, prize.describe()); 
     oos.writeObject(writeOut); 
     System.out.println("wrote to " + arg); 
    } catch (Exception e) { 
     System.out.println("Problem"); 
     e.printStackTrace(); 
    } 
} 
+1

または、それらはメソッド呼び出しの存続期間中のみ使用されるため、ローカル変数にしてください。フィールドはここで目的を果たしていないようです。 'readIn'と' writeOut'と同じことです。それらはローカル変数でなければなりません。 – Radiodef

+1

['try-with-resources'](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)は、よりクリーンになります。 –

+0

それはそれを行い、ストリームを一時的に修正します。どうもありがとう。 (私は答えを受け入れるためにそれほど時間がかかります。 – Garrett

関連する問題