将对象附加到二进制文件

你有以下方法:

public static void writeToBinary(Object obj, String filename) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream(filename)); oos.writeObject(obj); } catch (Exception e) { e.printStackTrace(); } finally{ try{ if (oos != null) oos.close (); }catch (Exception e){ e.printStackTrace(); } } } 

如您所见,该方法将对象写入二进制文件。

但是现在您想要重写相同的方法以允许将对象附加到同一文件。
好的,你看一下java文档,你会发现你必须在FileOutputStream中添加一个值为true的参数:

 oos = new ObjectOutputStream(new FileOutputStream(filename, true)); 

你编译但是,哎呀!似乎它继续覆盖文件。

好吧,问题就开始了。 在google中搜索后,您会发现必须使用SAME ObjectOutputStream将对象附加到同一文件中。 你希望有一个函数,每次调用它时,它都会追加一个对象。 即:

 writeToBinary("a", filename); writeToBinary("b", filename); 

但正如我之前所说,你必须使用相同的ObjectOutputStream。

解决方案1:

 ObjectOutputStream out = getOutputStream (filename); writeToBinary("a", out); writeToBinary("b", out); writeToBinary("c", out); out.close (); 

这非常难看,因为我想隐藏流的使用。

还有其他解决方案吗?

编辑:该方法是静态的。 它位于实用程序类中,其中所有方法都是静态的。

编辑2:解决了! 附加到ObjectOutputStream 。 请参阅我的问题的已接受答案。 谢谢。

解决了。

 import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; public class Test{ private static String filename = "test"; public static void main(String[] args) { writeToBinary (filename, "a", true); writeToBinary (filename, "b", true); writeToBinary (filename, "c", true); readFromBinaryFile (filename); } public static void writeToBinary (String filename, Object obj, boolean append){ File file = new File (filename); ObjectOutputStream out = null; try{ if (!file.exists () || !append) out = new ObjectOutputStream (new FileOutputStream (filename)); else out = new AppendableObjectOutputStream (new FileOutputStream (filename, append)); out.writeObject(obj); out.flush (); }catch (Exception e){ e.printStackTrace (); }finally{ try{ if (out != null) out.close (); }catch (Exception e){ e.printStackTrace (); } } } public static void readFromBinaryFile (String filename){ File file = new File (filename); if (file.exists ()){ ObjectInputStream ois = null; try{ ois = new ObjectInputStream (new FileInputStream (filename)); while (true){ String s = (String)ois.readObject (); System.out.println (s); } }catch (EOFException e){ }catch (Exception e){ e.printStackTrace (); }finally{ try{ if (ois != null) ois.close(); }catch (IOException e){ e.printStackTrace (); } } } } private static class AppendableObjectOutputStream extends ObjectOutputStream { public AppendableObjectOutputStream(OutputStream out) throws IOException { super(out); } @Override protected void writeStreamHeader() throws IOException {} } } 

oos = new ObjectOutputStream(new FileOutputStream(filename,true)); 你编译但是,哎呀!似乎它继续覆盖文件。

那没有意义。 FileOutputStream是附加到现有文件的流,因此它不会覆盖该文件。 核实。

问题是无法关闭流并重新打开以序列化多个对象。 运行以下命令并比较生成的文件以进行检查。

 public class XX { public static void writeToBinary(Object obj, String filename) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true)); oos.writeObject(obj); oos.close(); } public static void writeToBinary2(Object obj1, Object obj2,String filename) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true)); oos.writeObject(obj1); oos.writeObject(obj2); oos.close(); } public static void main(String[] args) throws Exception { String s1= "hi, just trying"; String s2= "bye bye cruel world"; String filename = "/temp/f.dat"; String filename2 = filename + ".2" ; writeToBinary(s1, filename); writeToBinary(s2, filename); writeToBinary2(s1, s2,filename2); ObjectInputStream fin = new ObjectInputStream(new FileInputStream(filename)); // oops... works with filename2 Object x1 = fin.readObject(); Object x2 = fin.readObject(); System.out.println(x1); System.out.println(x2); } } 

写一个帮助类。 在构造函数中,它将实例化特定文件名的输出流。 然后使用一些append()writeToBinary()方法,它将附加数据。 在方法close() ,将对流进行flush()close()调用。

 BinaryWriteHelper helper = new BinaryWriteHelper("test.dat"); helper.writeToBinary("1"); helper.writeToBinary(2); helper.close(); 

在BinaryWriteHelper中:

 public BinaryWriteHelper(String filename) { this.stream = new ObjectOutputStream(new FileOutputStream(filename)); } public close() { // the cleanup here } 

试试这种方法:

  1. 将对象写入ByteArrayOutputStream
  2. ByteArrayOutputStream的大小和内容附加到RandomAccessFile
  3. 要从文件加载对象,请将表示Object的字节读入ByteArrayInputStream并在ObjectInputStream初始化ObjectInputStream 。 在每个对象字节序列之前的大小字段将在这里派上用场。