在C中截断文件开头的最佳方法是什么?

sna*_*pop 6 c

有许多类似的问题,但是在谷歌搜索之后没有任何具体的答案.开始:

假设我们有一个文件(可能是二进制文件,也可能更大):

abcdefghijklmnopqrztuvwxyz

C中最好的方法是将此文件的最右边部分"移动"到左侧,截断文件的开头..例如,"front truncating"7个字节会将磁盘上的文件更改为:

hijklmnopqrztuvwxyz

我必须避免使用临时文件,并且不希望使用大缓冲区将整个文件读入内存.我想到的一种可能的方法是使用带有"rb +"标志的fopen,并且不断地来回读取和写入从offset开始复制字节,然后将setEndOfFile截断到最后.这似乎是很多寻求(可能效率低下).

另一种方法是两次打开同一个文件,并将fgetc和fputc与相应的文件指针一起使用.这甚至可能吗?

如果还有其他方法,我很乐意阅读所有这些内容.

Nei*_*eil 6

您可以将文件映射到内存中,然后内存移动内容。您必须单独截断该文件。

  • @Banthar:比这更糟糕:您需要进程地址空间的连续部分足够大。这可能远小于 4GB,具体取决于碎片和其他内存分配。 (2认同)

Jon*_*ler 4

您不必使用巨大的缓冲区大小,并且内核将为您做艰苦的工作,但是,是的,从文件上方读取已满的缓冲区并在靠近开头处写入是执行此操作的方法,如果您无法完成创建新文件,将所需内容复制到该文件中,然后将新(临时)文件复制到旧文件的简单工作。我不排除将所需内容复制到新文件,然后移动新文件代替旧文件或将新文件复制到旧文件的方法会比您描述的洗牌过程更快的可能性。如果要删除的字节数是磁盘块大小,而不是 7 字节,情况可能会有所不同,但也可能不是。唯一的缺点是复制方法需要更多的中间磁盘空间。

假设您使用的是 POSIX 系统,您的大纲方法将需要使用truncate()或将文件缩短到适当的长度。ftruncate()如果您没有truncate(),那么您将需要进行复制。

"r+b"请注意,如果您在打开写入模式时小心不要破坏文件,则打开文件两次将可以正常工作fopen(),或者避免O_TRUNC使用open()