从C语言中删除文件中的行

时间:2009-07-20 04:33:29

标签: c file-io

我想删除文件中的某些行,并根据行的某些部分是否与指定的字符串匹配,在同一文件中插入某些行。有没有办法这样做而不使用临时文件来复制内容等等?

3 个答案:

答案 0 :(得分:28)

问题是,一个文件(基本上)是磁盘上的字节数组(或者其他任何物理基板,但无论如何都是字节!),“一行”可以占用不同数量的字节;所以插入或删除行(除非你总是严格用另一行完全相同的字节长度替换一行)将需要“转移”文件的所有其余部分“向上”或“向下”字节的差异...这可能是一个非常繁重的操作(因为文件的其余部分可以是千兆字节,即使你只是将一行的长度改为文件开头的1个字节)。

因此,这样的操作可能非常繁琐,因此通常不会在任何支持具有可变行长度的文件(C,Python,Java,C ++,Ruby或任何其他此类语言)的语言中提供原语。你真的需要在性能和风险上支付这样一个潜在的未约束成本(在GB的“转换”期间系统或磁盘崩溃或数据上升或下降可能会破坏整个巨大文件的可用性),这是极不可能的。你试图避免的完全简单,充足,快速,安全和合理的技术基本上都是零缺点(因此,为什么你要避免它,这远非明显?)。

使用与源文件不同的结果文件,当结果文件通过源文件完成时(大多数系统上的原子操作,如果你在同一个文件系统中),你真的有最好的世界。

答案 1 :(得分:3)

您不能轻易地“剪切”文件的一部分。你总是在某个地方制作临时副本。这不是C事;任何语言都是如此。

您可以mmap该文件,然后当您找到要删除的行时,您可以将其后的所有内容记忆到该行的起始位置。我会质疑它的效率如何;临时文件可能更快。

答案 2 :(得分:0)

如果文件不够大,无法在RAM上进行处理,那么您可以使用链接的字符串列表,其中每个节点代表一个Line,即链接列表的节点是基于'\ n'字符创建的,然后你可以根据需要在链表上进行插入操作和删除操作,然后你可以使用链表覆盖同一个文件。

例如,mytext.txt

  

这是一个测试文件

     

必须在

之上添加一行      

此行必须删除

现在,当您创建上述文件的链接列表时,它就像

  

[这是一个测试文件] - > [必须在上面添加一行] - > [此行必须删除] - > [NULL]

插入操作会将链接列表更改为

  

[这是一个测试文件] - > [这是一个新行] - > [必须在上面添加一行] - > [此行必须删除] - > [NULL]

删除操作会将链接列表更改为

  

[这是一个测试文件] - > [这是一个新行] - > [必须在上面添加一行] - > [NULL]

现在,您可以将链接列表写入mytext.txt文件,并在每个节点的末尾添加“\ n”字符。

最终文件是mytext.txt

  

这是一个测试文件

     

这是一个新行

     

必须在

之上添加一行