2013-04-22 11 views
6

hello dear同僚、複数のJavaオブジェクトを逆シリアル化する

私は複数のPlantクラスオブジェクトを直列化して逆シリアル化するGardenクラスを持っています。シリアライズは動作していますが、マイナススタティックメソッドで変数を呼び出すためにそれを割り当てる場合は、デシリアライズは機能しません。

public void searilizePlant(ArrayList<Plant> _plants) { 
    try { 
     FileOutputStream fileOut = new FileOutputStream(fileName); 
     ObjectOutputStream out = new ObjectOutputStream(fileOut); 
     for (int i = 0; i < _plants.size(); i++) { 
      out.writeObject(_plants.get(i)); 
     } 
     out.close(); 
     fileOut.close(); 
    } catch (IOException ex) { 
    } 
} 

デシリアライズコード:

public ArrayList<Plant> desearilizePlant() { 
    ArrayList<Plant> plants = new ArrayList<Plant>(); 
    Plant _plant = null; 
    try { 
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName)); 
     Object object = in.readObject(); 

     // _plant = (Plant) object; 


     // TODO: ITERATE OVER THE WHOLE STREAM 
     while (object != null) { 
      plants.add((Plant) object); 
      object = in.readObject(); 
     } 

     in.close(); 
    } catch (IOException i) { 
     return null; 
    } catch (ClassNotFoundException c) { 
     System.out.println("Employee class not found"); 
     return null; 
    } 
    return plants; 
} 

私の呼び出し元のコード:

ArrayList<Plant> plants = new ArrayList<Plant>(); 
plants.add(plant1); 
Garden garden = new Garden(); 
garden.searilizePlant(plants); 

// THIS IS THE PROBLEM HERE 
ArrayList<Plant> dp = new ArrayList<Plant>(); 
dp = garden.desearilizePlant(); 

編集私は@NilsHのソリューションが正常に動作している
nullポインタ例外が発生しました

、ありがとう!

+0

"それは機能していません"とはどういう意味ですか?コードはコンパイルされますか?実行時にエラーが発生しますか?どのようなエラーが正確に得られますか? – Jesper

+0

こんにちは、あなたが見ている正確な問題は何ですか?あなたは、(主な)静的メソッドの変数を呼び出すためにそれを割り当てたいのであれば、 "働かない"という意味ですか?デバッガでは、 'plants'配列が正しく構築されていますか? – wmorrison365

+0

また、IOクローズコールを 'finally'ブロックに入れる必要があります。また、 'ArrayList dp = new ArrayList ();'は必要ありません。あなたの配列が '#deserializePlant'で作成されたので、' ArrayList dp = garden.desearilizePlant(); 'を持っています – wmorrison365

答えて

16

代わりにリスト全体をシリアル化するのはどうですか?リスト内の個々のオブジェクトをシリアライズする必要はありません。

public void searilizePlant(ArrayList<Plant> _plants) { 
    try { 
     FileOutputStream fileOut = new FileOutputStream(fileName); 
     ObjectOutputStream out = new ObjectOutputStream(fileOut); 
     out.writeObject(_plants); 
     out.close(); 
     fileOut.close(); 
    } catch (IOException ex) { 
    } 
} 

public List<Plant> deserializePlant() { 
    List<Plants> plants = null; 
    try { 
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName)); 
     plants = in.readObject(); 
     in.close(); 
    } 
    catch(Exception e) {} 
    return plants; 
} 

これで問題が解決しない場合は、エラーの詳細を投稿してください。

+0

+1私はそれに行くだろう... – wmorrison365

+0

@NilsH非常に働いてくれてありがとう 変更:公開**リスト ** deserializePlant(){....} – imalik8088

0

(メモリの問題などにより)オブジェクトのリスト全体を逆シリアル化することは必ずしも実現可能ではないかもしれません。

ObjectInputStream in = new ObjectInputStream(new FileInputStream(
      filename)); 

    while (true) { 
     try { 
      MyObject o = (MyObject) in.readObject(); 
      // Do something with the object 
     } catch (EOFException e) { 
      break; 
     } 
    } 

    in.close(); 

またはJava SE 7のtry-と資源のステートメントを使用して:その場合の試みで、あなたが配列の線形リストにそれをシリアル化した場合

try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(
      filename))) { 
     while (true) { 
      MyObject o = (MyObject) in.readObject(); 
      // Do something with the object 
     } 
    } catch (EOFException e) { 
     return; 
    } 
+0

これは私にとっては役に立たなかった。ストリームの破損エラーが発生します。 http://stackoverflow.com/questions/23889486/java-io-streamcorruptedexception-wrong-format-when-reading-more-than-1-object – faizal

+0

@faizal出力ストリームの作成方法を変更する必要があります。あなたのwhile条件のために、その理由はhttp://stackoverflow.com/questions/1194656/appending-to-an-objectoutputstream – Tomasz

+0

を参照してください。既に消費されているにもかかわらず、あなたはストリームから読むでしょう。 –

0

、あなたは配列に戻って、それをキャストすることができます他のすべてのメソッドが失敗しました:

import java.io.*; 
import java.util.ArrayList; 
import java.util.Arrays; 

public class Program 
{ 
    public static void writeToFile(String fileName, Object obj, Boolean appendToFile) throws Exception 
    { 
     FileOutputStream fs = null; 
     ObjectOutputStream os = null; 
     try 
     { 
      fs = new FileOutputStream(fileName); 
      os = new ObjectOutputStream(fs); 

      //ObjectOutputStream.writeObject(object) inherently writes binary 
      os.writeObject(obj); //this does not use .toString() & if you did, the read in would fail 
     } 
     catch (FileNotFoundException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      try 
      { 
       os.close(); 
       fs.close(); 
      } 
      catch(Exception e) 
      { 
       //if this fails, it's probably open, so just do nothing 
      } 
     } 
    } 


    @SuppressWarnings("unchecked") 
    public static ArrayList<Person> readFromFile(String fileName) 
    { 
     FileInputStream fi = null; 
     ObjectInputStream os = null; 
     ArrayList<Person> peopleList = null; 
     try 
     { 
      fi = new FileInputStream(fileName); 
      os = new ObjectInputStream(fi); 
      peopleList = ((ArrayList<Person>)os.readObject()); 
     } 
     catch (FileNotFoundException e) 
     { 
      e.printStackTrace(); 
     } 
     catch(EOFException e) 
     {      
      e.printStackTrace(); 
     } 
     catch(ClassNotFoundException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      try 
      { 
       os.close(); 
       fi.close(); 
      } 
      catch(Exception e) 
      { 
       //if this fails, it's probably open, so just do nothing 
      } 
     } 
     return peopleList; 
    } 




    public static void main(String[] args) 
    { 
     Person[] people = { new Person(1, 39, "Coleson"), new Person(2, 37, "May") }; 
     ArrayList<Person> peopleList = new ArrayList<Person>(Arrays.asList(people)); 

     System.out.println("Trying to write serializable object array: "); 

     for(Person p : people) 
     { 
      System.out.println(p); 
     } 
     System.out.println(" to binary file"); 

     try 
     { 
      //writeToFile("output.bin", people, false); //serializes to file either way 
      writeToFile("output.bin", peopleList, false); //but only successfully read back in using single cast 
     }            // peopleList = (ArrayList<Person>)os.readObject(); 
                 // Person[] people = (Person[])os.readObject(); did not work 
                 // trying to read one at a time did not work either (not even the 1st object) 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 



     System.out.println("\r\n"); 




     System.out.println("Trying to read object from file. "); 
     ArrayList<Person> foundPeople = null; 
     try 
     { 
      foundPeople = readFromFile("input.bin"); 
     } 
     catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if (foundPeople == null) 
     { 
      System.out.println("got null, hummm..."); 
     } 
     else 
     { 
      System.out.println("found: "); 

      for(int i = 0; i < foundPeople.size(); i++) 
      { 
       System.out.println(foundPeople.get(i)); 
      } 

      //System.out.println(foundPeople); //implicitly calls .toString() 
     } 
    } 
} 
関連する問題