在java中删除数据文件的一部分

时间:2010-07-04 08:49:56

标签: java file-io

我有一个文件,我写了一些java对象。写完之后,有时我需要删除一些放在文件中ramndom位置的对象。有没有办法从文件中删除所选对象而不替换整个文件?

谢谢。

4 个答案:

答案 0 :(得分:5)

不,这基本上是大多数文件系统不支持的。 (可能有一些使用特殊的数据结构使其便宜,但大多数没有 - 并且标准API不支持这个想法。)

“删除”文件的一部分的最简单方法是将所需的位复制到新文件中。如果你只是删除接近结尾的位,你可能会避免再次复制它的开头,但这需要更复杂的代码。

在对象流的情况下,您可能最好只读取一个流中的对象,并将您仍想要的对象写入新流中。 (显然你可以在之后重命名输出文件。)通过自己查看序列化格式,你可以避免重复反序列化/序列化所需的一些处理,但我会选择简单的路径来开始。

答案 1 :(得分:2)

@Jon Skeet是对的。

我想知道在技术上是否可以做一些事情来将串行流中的对象变成......其他东西......用适当的字节模式覆盖它。我认为答案是否定的。

我能想到的最好的方法是用一系列0x73字节覆盖它...... null的表示形式;请参阅Java Object Serialization Specification Chapter 6。但这有三个严重的问题:

  • 使用0x73字节进行覆盖会将一个对象转换为多个null,这会让尝试读取序列化对象流的应用程序变得困难。
  • 如果流中的任何其他对象包含对被破坏对象的引用,那么这些引用将被破坏并且您将获得异常。
  • 要弄清楚要被破坏的对象的流的开始和字节偏移量是很困难的。

因此,实际上最好的答案是重写对象流,省略要删除的对象。

答案 2 :(得分:1)

您可以尝试使用RandomAccessFile并使用空格覆盖对象。 然后在离线模式下你可以截断它。

答案 3 :(得分:0)

你可以只标记你的对象以告诉它的自由空间而不实际删除它。要添加的下一个对象(如果适合)可以插入已创建的已删除对象的间隙中。显然有可能新对象不会完全填补空白留下一些空间,这称为内部碎片,你不得不期望它随着许多添加/删除周期而增加。

时不时地进行"碎片整理"运行以包装所有对象以去除所有小间隙。