Java writeObject()是否始终覆盖现有对象,从不追加?

Java writeObject()是否始终覆盖现有对象,从不追加?,java,object,file-io,Java,Object,File Io,我想使用ObjectOutputStream.writeObject()将哈希表序列化为文件,但我希望编写器始终覆盖任何现有对象,以便只存在一个对象: FileOutputStream fout=新的FileOutputStream(f); ObjectOutputStream编写器=新的ObjectOutputStream(fout); writeObject(哈希表); writer.flush(); hastable在运行时会间歇性更新,因此我使用一个助手方法来保持其状态: privat

我想使用
ObjectOutputStream.writeObject()
将哈希表序列化为文件,但我希望编写器始终覆盖任何现有对象,以便只存在一个对象:

FileOutputStream fout=新的FileOutputStream(f);
ObjectOutputStream编写器=新的ObjectOutputStream(fout);
writeObject(哈希表);
writer.flush();
hastable在运行时会间歇性更新,因此我使用一个助手方法来保持其状态:

private void persistObject(哈希表ht){
writer.writeObject(ht);
writer.flush();
}

问题是每次我调用
writeObject()
,文件中都会追加一个新的hastable;有没有办法覆盖文件中的任何内容,从而只保留一个对象

最简单的方法是关闭并重新打开文件,只需在persistObject()方法中重新运行以下代码:


最简单的方法是关闭并重新打开文件,只需在persistObject()方法中重新运行以下代码:


如果要放弃文件内容并再次从文件开头开始写入,可以获取其频道并重新定位内容。问题是,ObjectStreams使用一些内部头,如果我们想“重置”流,我们需要考虑这一点

实例化
ObjectOutputStream
后,存储初始位置(
writeStreamHeader
写入两条短消息-消耗4个字节,但最好是通用的,而不是抱歉),这样您就可以定位频道而不覆盖报头

final long initialPosition = fout.getChannel().position();
然后,每次必须写入内容时,跳过初始字节(通过定位通道),重置流并写入对象:

//java 1.7
private void persistObject(Hashtable ht){
   fout.getChannel().position(initialPosition);
   fout.reset();
   writer.writeObject(ht);
   writer.flush();
}

正如@bgp所提到的,我不认为打开/关闭文件会带来那么多开销。。。此外,我不认为每次写入时截断和刷新磁盘是有效的,也不认为长时间打开文件流是一种好的做法(或安全的做法),但破解
ObjectOutputStream
还是很有趣的

如果要放弃文件内容并再次从文件开头开始写入,可以获取其频道并重新定位内容。问题是,ObjectStreams使用一些内部头,如果我们想“重置”流,我们需要考虑这一点

实例化
ObjectOutputStream
后,存储初始位置(
writeStreamHeader
写入两条短消息-消耗4个字节,但最好是通用的,而不是抱歉),这样您就可以定位频道而不覆盖报头

final long initialPosition = fout.getChannel().position();
然后,每次必须写入内容时,跳过初始字节(通过定位通道),重置流并写入对象:

//java 1.7
private void persistObject(Hashtable ht){
   fout.getChannel().position(initialPosition);
   fout.reset();
   writer.writeObject(ht);
   writer.flush();
}


正如@bgp所提到的,我不认为打开/关闭文件会带来那么多开销。。。此外,我不认为每次写入时截断和刷新磁盘是有效的,也不认为长时间打开文件流是一种好的做法(或安全的做法),但破解
ObjectOutputStream
还是很有趣的

您应该在persistObject中打开/写入/关闭ObjectOutputStream。不应截断位置0处的文件。ObjectOutputStream具有复杂的结构,不仅是对象数据,还有标头、类描述符等。截断会破坏它,导致尝试读取时出现StreamCorruptedException。

您应该在persistObject中打开/写入/关闭ObjectOutputStream。不应截断位置0处的文件。ObjectOutputStream具有复杂的结构,不仅是对象数据,还有标头、类描述符等。截断会破坏它,导致尝试读取时出现StreamCorruptedException。

我认为这是
FileOutputStream
的默认行为,覆盖,不附加…可能是错误的:P@MadProgrammer如果文件保持打开状态,这不是默认行为;它只是一直在追加。是的,没有以那种方式读取代码我认为这是
FileOutputStream
的默认行为,覆盖,而不是追加…可能是错误的:P@MadProgrammer如果文件保持打开状态,这不是默认行为;它只是一直在追加。是的,没有那样读代码(…别忘了关闭流…)是的,我想过,但我必须保持文件打开。它是一个服务器,哈希表保持经常变化的临界状态;希望避免打开/关闭文件的开销。Gotcha-IMO这个开销可能不值得担心。在现代操作系统上,它将非常小,而且通常内核在缓存与经常使用的文件相关的信息方面做得很好(也就是说,如果经常这样做,打开和关闭文件的开销不会很大)。哈希表(大致)有多大?它不大,几千个对象我同意@StevenSchlansker的观点-close()是必要的,flush()不是。这个问题包括:(…别忘了关闭流…)是的,我想过了,但我必须保持文件打开。它是一个服务器,哈希表保持经常变化的临界状态;希望避免打开/关闭文件的开销。Gotcha-IMO这个开销可能不值得担心。在现代操作系统上,它将非常小,而且通常内核在缓存与经常使用的文件相关的信息方面做得很好(也就是说,如果经常这样做,打开和关闭文件的开销不会很大)。哈希表(大致)有多大?它不大,几千个对象我同意@StevenSchlansker的观点-close()是必要的,flush()不是。这个问题涵盖了它:很好-正在寻找,我还没有测试,但这看起来像@raffian所要求的。我使用您的方法写入文件,但在启动时我读取了文件;这不是问题的一部分,但是如果您的方法有效,那么应该使用