< 返回版块

WingDust 发表于 2021-12-16 11:54

Tags:io,memap

我有一个每行为100字节的文件 我想精准的在任意位置删除、添加一行 自己查到的 io 处理有 File::set_len memap 不知道怎么能用 memap 实现精准的在任意位置删除、添加一行

如果能更好的方法也请列出来

评论区

写评论
Pikachu 2021-12-16 16:06

假设1:忽略文件系统的block大小等细节,把硬盘视为一条一维的纸带。 假设2:换行符是LF,ASCII十六进制为0x0A。

首先,从文件存储的角度来讲,没有在文件中间插入、删除的操作。在文件中间插入内容,实质上是把原有内容往后移动并重新写入磁盘,然后在腾出来的空间内写入新的内容。

然后,从比较底层的视角来看,也不存在“每行为100字节”,因为文件本身并不对换行符和普通字符区别对待。如果你直接以[u8]读入文件的话,你所能注意到的规律是每隔100个字节会出现一次0x0A。

综上,在一个共有n行的文件中,如果你想要在第i行后插入一行,你的问题可以等价为:“如何在文件的第101×i101×i+1字节中间插入101个字节”。答案是把从第101×i+1字节起的后续内容往后移动101个字节,在空出来的空间写入你需要的内容。

PS:如果每行长度+换行符长度=文件系统block大小的话,理论上确实可以通过分配新block、修改inode来实现在文件中间插入。但是这种操作已经超出了我的知识范围,看看有没有其他。

Neutron3529 2021-12-16 15:43

连输入和输出都没有,不会有人给你解答的。

我的第一反应是Vec<Vec<[u8;100]>>,这样可以快速定位到每一行,而且小批量增加和删除都比较快,缺点是定位行列不准确。

第二反应是维护一个树,在第一反应的基础上加一个可以在O(log n)的时间内查询第一层Vec的第一个元素对应第几行的树状数组,坏处是增删行列的时候需要用额外O(log n)的时间修改数组

第三反应是HashMap,速度最快,但会打乱文件的顺序

作者 WingDust 2021-12-16 11:54

最好有 Demo

1 共 3 条评论, 1 页