2010-06-13 132 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