在 RandomAccessFile 中插入数据并更新索引
我有一个 Java 中的 RandomAccessFile 来管理一些数据。简化: 在文件的开头我有一个索引。 (每个数据集 8 个字节长的值,表示可以找到实际数据的偏移量)。
因此,如果我现在想在哪里可以找到例如数据集 3 的数据。我在偏移量 (2*8) 处读取了 8 个字节。 (索引从0开始)。
数据集本身由 4 个字节组成,表示数据集的大小,然后是属于该数据集的所有字节。
因此,如果我总是重写整个文件,那么效果很好。
这里非常重要的是,数据集 3 可以被写入文件中的第一个条目,因此索引是有序的,而不是数据本身。
如果我插入新的数据集,我总是将其附加到文件的末尾。但一个文件中可以包含的数据集数量是有限的。如果我可以在文件中存储 100 个数据集,那么索引中将始终有 100 个条目。如果从数据集索引读取的偏移量为 0,则该数据集是新数据集并将被追加到文件中。
但是有一个案例对我来说还不起作用。如果我读数据集没有。 3 从文件中,我在应用程序中添加了一些数据,我想在文件中更新它,但我不知道如何执行此操作。
如果它的长度与以前相同,我可以简单地覆盖旧数据。但是,如果新数据集比旧数据集具有更多字节,我将必须移动该数据集后面的文件中的所有数据并更新这些数据集的索引。
知道该怎么做吗? 或者是否有更好的方法来管理将这些数据集存储在文件中?
PS:是的,我当然想过使用数据库,但这不适用于我的项目。我确实需要简单的文件。
I've got a RandomAccessFile in Java where i manage some data. Simplified:
At the start of the file i have an index. (8 byte long value per dataset which represents the offset where the real data can be found).
So if i want to now where i can find the data of dataset no 3 for example. I read 8 Bytes at offset (2*8). (Indexing starts with 0).
A dataset itsself consists of 4 Bytes which represents the size of the dataset and then all the bytes belonging to the dataset.
So that works fine in case i always rewrite the whole file.
It's pretty important here, that Dataset no 3 could have been written as the first entry in the file so the index is ordered but not the data itsself.
If i insert a new dataset, i always append it to the end of the file. But the number of datasets that could be i n one file is limited. If i can store 100 datasets in the file there will be always 100 entries in the index. If the offset read from the index of a dataset is 0 the dataset is new and will be appended to the file.
Bu there's one case which is not working for me yet. If i read dataset no. 3 from the file and i add some data to it in my application and i want to update it in the file i have no idea how to do this.
If it has the same length as befor i can simply overwrite the old data. But if the new dataset has more bytes than the old one i'll have to move all the data in the file which is behind this dataset and update the indexes for these datasets.
Any idea how to do that?
Or is there maybe a better way to manage storing these datasets in a file?
PS: Yes of course i thought of using a database but this is not applicable for my project. I really do need simple files.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您无法轻松地将数据插入文件的中间。您基本上必须读取所有剩余数据,写入“新”数据,然后重写“旧”数据。或者,您可能会使旧的“慢”记录无效(可能允许稍后重用它),然后将整个新记录写入文件末尾。说实话,你的文件格式对我来说并不是很清楚,但从根本上来说,你需要知道你不能在文件中间插入(或删除)。
You can't easily insert data into the middle of a file. You'd basically have to read all the remaining data, write the "new" data and then rewrite the "old" data. Alternatively, you could potentially invalidate the old "slow" (potentially allowing it to be reused later) and then just write the whole new record to the end of the file. Your file format isn't really clear to me to be honest, but fundamentally you need to be aware that you can't insert (or delete) in the middle of a file.
就停在那里。您有一个文件。您目前正在通过 Java 中的 RandomAccessFile 访问它。然而,您的整个问题与文件本身有关,而不是与 RandomAccessFile 或 Java 相关。你有一个主要的文件设计问题,因为你假设像插入到文件中间这样的功能在我自 1979 年以来使用过的任何文件系统中都不存在。
Stop right there. You have a file. You are presently accessing it via RandomAccessFile in Java. However your entire question relates to the file itself, not to RandomAccessFile or Java. You have a major file design problem, as you are assuming facilities like inserting into the middle of a file that don't exist in any filesystem I have used since about 1979.
正如其他人也回答的那样,在不重写整个文件的情况下,不可能使文件更长/更短。有一些解决方法,也许一种解决方案会起作用。
大多数解决方案都有数据开销,但文件大小通常不是问题,正如前面提到的,您可以让某种方法“清理它”。
PS:我希望可以回答这些老问题 - 我在帮助中心找不到任何相关内容,而且我在这里相对较新。
As the others answered too, there's no real possibility to make the file longer/shorter without rewriting the whole. There are some workarounds and maybe one solution would work after all.
Most solutions have a data overhead but file size is usually not the problem and as mentioned you can let some method "clean it up".
PS: I hope it's ok to answer such old questions - I couldn't find anything about it in the help center and I'm relatively new here.