java 将对象附加到二进制文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4646272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Appending objects to a binary file
提问by Gabriel Llamas
Supose you have the following method:
假设您有以下方法:
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();
}
}
}
As you can see, the method writes an object to a binary file.
如您所见,该方法将对象写入二进制文件。
But now you want to rewrite the same method to allow appending objects to the same file.
Ok, you look at the java documentation and you see that you have to add a parameter with value true to the FileOutputStream:
但是现在您想重写相同的方法以允许将对象附加到同一个文件中。
好的,您查看 java 文档,您会发现必须向 FileOutputStream 添加值为 true 的参数:
oos = new ObjectOutputStream(new FileOutputStream(filename, true));
You compile but, whoops!, it seems that it continues overriding the file.
Well, the problems begin. After searching in google you read that you have to use the SAMEObjectOutputStream to append objects to the same file. You want to have a function that every time you call it, it appends an object. I.e. :
您编译但是,哎呀!,它似乎继续覆盖该文件。
好吧,问题开始了。在谷歌搜索后,你读到你必须使用SAMEObjectOutputStream 将对象附加到同一个文件。您希望有一个函数,每次调用它时,它都会附加一个对象。IE :
writeToBinary("a", filename);
writeToBinary("b", filename);
But as I said before, you have to use the same ObjectOutputStream.
但正如我之前所说,您必须使用相同的 ObjectOutputStream。
Solution 1:
解决方案1:
ObjectOutputStream out = getOutputStream (filename);
writeToBinary("a", out);
writeToBinary("b", out);
writeToBinary("c", out);
out.close ();
This is very ugly because I want to hide the usage of streams.
Is there any other solution?
EDIT: The method is static. It is inside an utility class where all methods are static.
EDIT2: SOLVED! Appending to an ObjectOutputStream. See accepted answer to my question.
Thanks.
这非常难看,因为我想隐藏流的使用。
还有其他解决方案吗?
编辑:该方法是静态的。它位于一个实用程序类中,其中所有方法都是静态的。
EDIT2:解决了!附加到 ObjectOutputStream。请参阅我的问题的已接受答案。谢谢。
回答by Gabriel Llamas
Solved.
解决了。
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 {}
}
}
回答by leonbloy
oos = new ObjectOutputStream(new FileOutputStream(filename, true)); You compile but, whoops!, it seems that it continues overriding the file.
oos = new ObjectOutputStream(new FileOutputStream(filename, true)); 您编译但是,哎呀!,它似乎继续覆盖该文件。
That does not make sense. The FileOutputStream is a streams that appends to the existing file, so it will not overwite the file. Check it.
那没有意义。FileOutputStream 是附加到现有文件的流,因此它不会覆盖文件。核实。
The problem is that a stream cannot be closed and reopened to serialize several objects. Run the following and compare the resulting files to check it.
问题是无法关闭并重新打开流以序列化多个对象。运行以下命令并比较生成的文件以进行检查。
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);
}
}
回答by Vladimir Ivanov
Write a helper class. In constructor it will instantiate an output stream for a particular file name. Then using some append()
or writeToBinary()
method it will append the data. on method close()
there will be flush()
and close()
calls on the stream.
编写一个辅助类。在构造函数中,它将为特定文件名实例化输出流。然后使用 someappend()
或writeToBinary()
method 它将附加数据。在方法close()
上将有flush()
并close()
调用流。
BinaryWriteHelper helper = new BinaryWriteHelper("test.dat");
helper.writeToBinary("1");
helper.writeToBinary(2);
helper.close();
in BinaryWriteHelper :
在 BinaryWriteHelper 中:
public BinaryWriteHelper(String filename) {
this.stream = new ObjectOutputStream(new FileOutputStream(filename));
}
public close() {
// the cleanup here
}
回答by Vijay Mathew
Try this approach:
试试这个方法:
- Write the object to a
ByteArrayOutputStream
. - Append the the size and contents of the
ByteArrayOutputStream
to aRandomAccessFile
. - To load an object from the file, read the bytes that represent an Object into a
ByteArrayInputStream
and initialize anObjectInputStream
on this. The size field that was prepends each object byte sequence will come handy here.
- 将对象写入
ByteArrayOutputStream
. - 将 的大小和内容附加
ByteArrayOutputStream
到 aRandomAccessFile
。 - 要从文件加载对象,请将表示对象的字节读入 a
ByteArrayInputStream
并在其ObjectInputStream
上初始化 an 。在每个对象字节序列前面的大小字段在这里会派上用场。