2010-06-13 153 views
4

是否可以使用Java將對象寫入二進制文件?我想要寫的對象是2個String對象的數組。我想這樣做的原因是爲了保存持久數據。如果有更簡單的方法可以讓我知道。將Java對象寫入文件

+0

我改變了我的問題,因爲我想我不想寫類。 – 2010-06-13 00:50:55

+0

比什麼更容易? – EJP 2016-09-05 09:34:59

回答

1

如果你想寫字符串數組,你最好用文本文件。使用文本文件的優點是可以很容易地查看,編輯並且可以被系統中的許多其他工具使用,這意味着您不必自己編寫這些工具。

您還可以發現簡單的文本格式比使用XML或JSON更快,更緊湊。注意:這些格式對於複雜的數據結構更加有用。

public static void writeArray(PrintStream ps, String... strings) { 
    for (String string : strings) { 
     assert !string.contains("\n") && string.length()>0; 
     ps.println(strings); 
    } 
    ps.println(); 
} 

public static String[] readArray(BufferedReader br) throws IOException { 
    List<String> strings = new ArrayList<String>(); 
    String string; 
    while((string = br.readLine()) != null) { 
     if (string.length() == 0) 
      break; 
     strings.add(string); 
    } 
    return strings.toArray(new String[strings.size()]); 
} 

如果有

String[][] theData = { { "a0 r0", "a0 r1", "a0 r2" } {"r1 c1"} }; 

你開始這可能導致

a0 r0 
a0 r1 
a0 r2 

r1 c1 

正如你可以看到這是很容易編輯/查看。

這對字符串可以包含什麼做了一些假設(請參閱資產)。如果這些假設無效,那麼有辦法解決這個問題。

13

你可以

  1. 序列化陣列,或包含數組類 。
  2. 將數組寫成格式爲 的兩行,例如JSON,XML或CSV。

這裏是第一個(你可以以與陣列替換隊列) 序列化

public static void main(String args[]) { 
    String[][] theData = new String[2][1]; 

    theData[0][0] = ("r0 c1"); 
    theData[1][0] = ("r1 c1"); 
    System.out.println(theData.toString()); 

    // serialize the Queue 
    System.out.println("serializing theData"); 
    try { 
     FileOutputStream fout = new FileOutputStream("thedata.dat"); 
     ObjectOutputStream oos = new ObjectOutputStream(fout); 
     oos.writeObject(theData); 
     oos.close(); 
     } 
    catch (Exception e) { e.printStackTrace(); } 
} 

一些代碼反序列化

public static void main(String args[]) { 
    String[][] theData; 

    // unserialize the Queue 
    System.out.println("unserializing theQueue"); 
    try { 
    FileInputStream fin = new FileInputStream("thedata.dat"); 
    ObjectInputStream ois = new ObjectInputStream(fin); 
    theData = (Queue) ois.readObject(); 
    ois.close(); 
    } 
    catch (Exception e) { e.printStackTrace(); } 

    System.out.println(theData.toString());  
} 

第二個是更復雜的,但具有人類以及其他語言可讀的好處。

讀,寫爲XML

import java.beans.XMLEncoder; 
import java.beans.XMLDecoder; 
import java.io.*; 

public class XMLSerializer { 
    public static void write(String[][] f, String filename) throws Exception{ 
     XMLEncoder encoder = 
      new XMLEncoder(
       new BufferedOutputStream(
       new FileOutputStream(filename))); 
     encoder.writeObject(f); 
     encoder.close(); 
    } 

    public static String[][] read(String filename) throws Exception { 
     XMLDecoder decoder = 
      new XMLDecoder(new BufferedInputStream(
       new FileInputStream(filename))); 
     String[][] o = (String[][])decoder.readObject(); 
     decoder.close(); 
     return o; 
    } 
} 

要和從JSON

谷歌有一個好的庫轉換爲從JSON在http://code.google.com/p/google-gson/你可以簡單地寫你的對象JSON和然後寫入文件。閱讀做相反的事情。

+0

+1 JSON可以在這裏工作,但要小心使用它來進行通用序列化 - 它不支持循環引用。 – mdma 2010-06-13 02:11:32

+0

對序列化的每個相關對象(如果有的話)也實現Serializable非常重要。 實施後,它會要求您生成密鑰。也這樣做。 – 2012-02-15 11:08:57

2

除了序列化之外,還有一種可能性是將對象寫入XML文件,以使其更具人類可讀性。 XStream API能夠做到這一點,並使用類似於序列化的方法。

http://x-stream.github.io/

2

您可以使用Java的serialization機制做到這一點,但要注意系列化不是對象的長期持久存儲一個很好的解決方案。原因是序列化對象與Java代碼緊密耦合:如果更改程序,則序列化的數據文件變得不可讀,因爲它們不再與Java代碼兼容。序列化適用於臨時存儲(例如用於磁盤緩存)或通過網絡傳輸對象。

對於長期存儲,您應該使用與您的Java代碼沒有緊密耦合的標準且有詳細記錄的格式(例如XML,JSON或其他)。

如果出於某種原因,您絕對要使用二進制格式,那麼有幾個選項可用,例如Google protocol buffersHessian

+0

如果您沒有定義serialVersionUID並且違反對象序列化規範版本控制章節中指定的規則,那麼只有在'如果更改程序'開始的部分纔是真實的。 – EJP 2016-09-05 09:37:24