Deleting parts of a data file in java
I have a file which I write some java objects. After writing, sometimes I need to delete some of these objects placed at ramndom positions in the file. Is there a way to delete a selected object from the file without replacing the whole f开发者_StackOverflow中文版ile?
Thank you.
No, this is fundamentally something that most file systems don't support. (There may be some with special data structures to make it cheap, but most don't - and the standard APIs don't support the idea.)
The simplest way of "deleting" part of a file is to copy just the bits you want to a new file. If you're only removing bits near the end, you could potentially avoid copying the start of it again, but that would require more complicated code.
In the case of a stream of objects, you'd probably be best to just read objects from one stream, and write the ones you still want into a new one. (Obviously you can rename the output file afterwards.) It's possible that by looking at the serialization format yourself you could avoid some of the processing required by repeated deserialization/serialization, but I'd go for the simple route to start with.
@Jon Skeet is correct.
I was wondering if it would be technically possible to do something that to turn an object in a serial stream into ... something else ... by overwriting it with an appropriate byte pattern. I think that the answer is no.
The best I could think of was to overwrite it with a sequence of 0x73
bytes ... the representation of a null
; refer to the Java Object Serialization Specification Chapter 6. But this has three serious problems:
- Overwriting with
0x73
bytes would turn one object into multiplenull
s, which would make life difficult for the application trying to read the serialized object stream. - If any other objects in the stream contained references to the clobbered object, those references would be broken and you'd get an exception.
- It would be difficult to figure out the start and byte offsets with the stream for the objects to be clobbered.
So, in practice the best answer is to rewrite the object stream, omitting the objects that you want to delete.
You can try using RandomAccessFile and overwrite the object with blanks. Then in offline mode you could truncate it.
you could just mark your object to tell it's free space without actually deleting it. The next object to add, if it fits in, could be inserted in the gap the deleted object created. Obviously chances are that the new object will not fill the gap perfectly leaving some space, that's called internal fragmentation and you have to expect it to increase with many add/delete cycles.
Every now and then perform a "defragmentation" run to pack all the objects togheter removing all the small gaps.
精彩评论