为什么无法就地从文件中间删除字符?



假设我有一个文件,其中有几行文本:

a
b
c
d
e

我想删除b字符,但不需要重写整个文件。据我所知,这是不可能的。为什么?


我试图更好地理解像SQLite这样的东西是如何工作的;文件";,但显然并不是所有的操作都附加到文件中。这是我目前对限制的理解:

  • 您可以在不重写整个文件的情况下将数据附加到文件中
  • 只要不更改文件中的字节数,就可以覆盖文件中间的数据
  • 在不重写整个文件的情况下,不能任意从文件中删除字节

为什么存在这些限制?是文件系统/OS吗?还有其他平台可以做到这一点吗?如果SQLite是一个有用的例子,那么在SQLite的上下文中回答(以及它如何处理这些限制)将是非常棒的!


让我走到这一步的阅读材料:

https://www.sqlite.org/fileformat.html

为什么SQLite存储数百个空字节?

C#用恒定时间覆盖文本文件的前几行

替换二进制文件中的字节序列

在操作系统级别,磁盘(SSD或旋转铁锈)被分解为逻辑块。默认情况下,Windows和Linux都使用4k。O/S不处理任何小于块的内容——一个1字节的文件(至少)占用1个块。格式化磁盘或分区时,大多数O/S都可以调整块大小。

到您的直接点:

  • 如果文件小于一个块,则可能需要重写整个文件以进行追加。如果您有一个更大的文件,那么在追加时可能仍然需要写入最后一个块
  • 如果您的文件大于单个块,那么您可以在在中间重写数据。如果大小相同,那么很可能是单个块写入。但如果它改变了大小,那么可能会有一些区块的重新排列
  • 根据文件中删除块的位置,可能只需要重写一个块。删除开头的一个字节,整个文件可能会被重写

一些数据库历史上通过使用";生的";分区。我过去曾为Sybase数据库使用过原始分区(磁盘上未格式化的分区)。基本上,这意味着数据库可以在一定程度上决定正确的块大小。底层硬件可以向上或向下限制块的大小。

如果您不使用原始分区,那么您将依赖O/S为您执行I/O。它应该足够快,这样你就不在乎那些方块了。在最底层,DB拥有它为数据和索引维护的内部结构。每个DB供应商都有自己的方式,通常可以根据您的用例进行调整。如果您有许多小的行,那么将磁盘格式化为更小的块可能是有意义的,以允许通过更新或插入传输更少的字节。相反,大量数据可能受益于8k或16k块大小。

最新更新