【问题标题】:Adding content to middle of file..without reading it till the end将内容添加到文件中间..直到最后才阅读
【发布时间】:2013-06-16 16:33:32
【问题描述】:

我在 unix.stackexchange 上阅读了有关如何在文件中添加或删除行而不需要创建临时文件的各种问题/答案。

https://unix.stackexchange.com/questions/11067/is-there-a-way-to-modify-a-file-in-place?lq=1

似乎所有这些答案都需要至少阅读到文件末尾,如果输入是一个大文件,这可能会很耗时。有没有解决的办法?我希望文件系统可以像链表一样实现......所以应该有一种方法可以达到所需的“行”,然后只需添加东西(链表中的节点)。我该怎么做?

我这样想对吗?还是我错过了什么?

Ps:我需要在 'C' 中完成此操作,并且不能使用任何 shell 命令。

【问题讨论】:

  • 文件不是作为链表实现的,所以没有一种简单的方法可以将数据插入到文件的中间。请参阅SO 10467711 了解处理将数据插入文件中间的代码,但请注意,它最终会将插入点后面的所有数据复制到正确的新位置。

标签: linux filesystems windows c


【解决方案1】:

简短的回答是,可以就地修改文件的内容,但是,不能在其中删除或添加内容文件的中间。

UNIX 文件系统使用inode pointer structure 实现,它指向整个数据块。文本文件的每一行并不“知道”它与上一行或下一行的关系,它们只是在块内彼此相邻。要在这两行之间添加内容,需要在块内进一步“向下”移动以下所有内容,将一些数据推送到下一个块中,而下一个块又必须移动到下一个块中,等等。

在 C 中你可以fopen a file for update 并读取它的内容,并覆盖其中的一些内容,但我不相信(甚至理论上)有任何方法可以在中间插入新数据或删除数据(除了覆盖它带有空值。

【讨论】:

  • 谢谢,你说的是正确的..但不幸的是我只能接受一个答案。所以我要投票了。
  • 文件系统不允许碎片化吗?例如,在某些情况下甚至是 ext4 碎片。
【解决方案2】:

从 Linux 4.1 开始,fallocate(2) 支持FALLOC_FL_INSERT_RANGE 标志,它允许在文件中间插入一个给定长度的孔而不重写以下数据。但是,它是相当有限的:必须在文件系统块边界处插入孔,并且插入的孔的大小必须是文件系统块大小的倍数。此外,在 4.1 中,此功能仅受 XFS 文件系统支持,在 4.2 中添加了对 Ext4 的支持。

对于所有其他情况,仍然需要重写文件的其余部分,如其他答案所示。

【讨论】:

  • 谢谢!您的回答是否符合我的问题:unix.stackexchange.com/q/281652/9689?我在那里引用了它,但是如果您将其添加为您自己的答案,我很乐意将其标记为答案并删除我的引用。 :)
【解决方案3】:

您可以就地修改文件,例如使用dd

$ echo Hello world, how are you today? > helloworld.txt
$ cat helloworld.txt
Hello world, how are you today?
$ echo -n Earth | dd of=helloworld.txt conv=notrunc bs=1 seek=6
$ cat helloworld.txt
Hello Earth, how are you today?

问题是,如果您的更改也更改了长度,它将无法正常工作:

$ echo -n Joe | dd of=helloworld.txt conv=notrunc bs=1 seek=6
Hello Joeth, how are you today?
$ echo -n Santa Claus | dd of=helloworld.txt conv=notrunc bs=1 seek=6
Hello Santa Clausare you today?

当您更改长度时,您必须重新编写文件,如果不完全,则从您所做的更改点开始。

在 C 中,这与 dd 相同。你打开文件,你寻找,你写。

【讨论】:

    【解决方案4】:

    您可以以读/写模式打开文件。您读取文件(或使用“seek”跳转到您想要的位置,如果您知道的话),然后写入文件,但您会覆盖此处的数据(这不是插入)。 然后你可以选择从你写的最后一点开始截断文件,或者在你写的那一点之后保留所有剩余的数据而不读取它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      相关资源
      最近更新 更多