2013-04-22 120 views
6

你好親愛的同事,反序列化多個Java對象

我有一個Garden類,我在其中序列化和反序列化多個Plant類對象。序列化工作正常,但如果想要將其分配給mein靜態方法中的調用變量,則反序列化不起作用。

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的解決方案工作正常,謝謝!

+0

你說的「它不工作」是什麼意思?代碼是否編譯?你在運行時遇到錯誤嗎?你準確得到什麼錯誤? – Jesper 2013-04-22 11:12:57

+0

嗨,你看到什麼確切的問題?你是什​​麼意思,它「不工作,如果要分配給(主)靜態方法調用變量」?在調試器中,您是否看到正確構建的「植物」數組? – wmorrison365 2013-04-22 11:15:01

+0

另外,您需要將IO關閉調用放在'finally'塊中。此外,您不需要ArrayList dp = new ArrayList ();'。只需要'ArrayList dp = garden.desearilizePlant();'因爲你的數組是在'#deserializePlant'中創建的 – wmorrison365 2013-04-22 11:16:24

回答

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 2013-04-22 11:17:40

+0

@NilsH非常感謝它的工作 更改:公開**列表 ** deserializePlant(){....} – imalik8088 2013-04-22 20:07:59

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

這並不適用於我。我收到一個Stream腐敗錯誤。請參閱http://stackoverflow.com/questions/23889486/java-io-streamcorruptedexception-wrong-format-when-reading-more-than-1-object – faizal 2014-05-27 16:51:14

+0

@faizal需要修改輸出流的創建方式。請參閱http://stackoverflow.com/questions/1194656/appending-to-an-objectoutputstream – Tomasz 2014-05-27 20:34:01

+0

它是因爲你的條件。儘管它已被使用,您仍將從流中讀取。 – 2015-01-20 14:35:16

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() 
     } 
    } 
}