添加和删除文件以不完全重写文件的最有效方法是啥?
Posted
技术标签:
【中文标题】添加和删除文件以不完全重写文件的最有效方法是啥?【英文标题】:What is the most effecient way of adding and removing pieces of file to not rewrite it fully?添加和删除文件以不完全重写文件的最有效方法是什么? 【发布时间】:2013-09-12 15:10:51 【问题描述】:例如,如果我想删除文件中间的 10 个字节或在中间添加 10 个字节,有没有办法在不完全重写文件的情况下做到这一点?
我想要一个最快完成这项任务的解决方案。
我使用 C#,但解决方案也可能是 C 或 C++。
【问题讨论】:
快速解决方案,如您获得快速答案或该解决方案具有快速性能? 我不知道有什么方法可以做到这一点。您可能希望考虑一种不需要从中间添加或删除字节的替代文件格式。 @Keith Payne - 能够以足够快的速度重复修改 1gb+ 文件的解决方案。 使用这些语言中的任何一种 @Manu343726:OP 的问题与语言无关。文件处理是一个操作系统问题。 【参考方案1】:您必须复制整个文件,省略或插入相关字节。这是一个操作系统约束;由于文件在磁盘上的布局方式,根本不可能支持这种类型的操作(至少对于像 Unix 或 Windows 使用的简单文件系统)。
【讨论】:
供我参考:整个文件还是从发生插入/删除的位置开始? @MM.:理论上,您可以将文件的其余部分读入内存,然后将其写回磁盘并进行正确的修改。实际上,您很少想要这样做 - 例如,中间的崩溃可能会使文件处于不可用状态。 @MM。正如 Jerry 所说,仅从插入或删除的角度来看,如果您不介意不时损坏文件。问题是您修改的字节位于磁盘上的物理位置;大多数文件系统没有办法说位置 x 的 n 个字节应该被忽略,或者在位置 x,你必须从其他地方获取 n 个字节,所以唯一的解决方案是在磁盘上的更改。【参考方案2】:尝试使用MapViewOfFile 的东西。可能有 C# 绑定。
然后您可以将文件视为内存,它应该是快速的。
【讨论】:
这类似于 unix mmap。它将文件映射到您当前的地址空间。然后,您可以像修改内存一样修改文件,因此应该可以进行就地编辑。 如果文件适合实际 RAM,这可能会有所帮助并且您必须在缓存达到写回 HDD 的超时之前进行许多编辑。最后,在 10GB 文件开头插入 1 字节仍然会触发所述文件的完全重写。 那是关于操作系统如何管理文件的。磁盘上的数据以块的形式存在,操作系统一次只会加载文件的几个块。如果您只是更改一些数据,则无需触摸未受影响的块。 是的,但是如果你添加/删除数据而不是修改它,你必须跨块边界移动所有内容!! 那么您将遇到与将数据插入内存块相同的问题。最后一点必须被复制【参考方案3】:如果你想在同一个地方做删除和添加 ==> 修改/更新
在 r+ 模式下打开文件这将使您更改为读取和写入都可以执行的操作。 那么
将文件流移动到您要修改的位置并在那里添加那么多字节 您无需删除 10 个字节。需要写10个字节。这将从当前位置覆盖十个字节。只是删除旧的十个字节并添加新的十个字节。
如果你想删除并且不想添加任何东西,然后复制到新文件,除了这十个字节。
如果你只想添加,将流位置移动到 end ,写入十个字节。
你需要fseek()
【讨论】:
OP 想要在中间插入 10 个字节,而不是覆盖它们。此外,他说他知道涉及复制除待删除字节之外的所有内容的解决方案。 @us2012 删除文件中间的10个字节或添加10个字节到中间,听起来是不是修改或更新? 对不起,真的是添加或删除,所以总文件应该或多或少变成10个字节。 @Kosmos 如果您在文件末尾写入 10 个字节。您的文件大小将增加十个字节。如果您在中间写入,即如果您覆盖现有字节,则文件大小保持不变。如果您删除...糟糕,我们无法删除文件内容。您可以在这十个字节处添加一些 ******** 而不是删除,并将其视为从文件中删除。经过多次删除后,您的文件中有很多 *****。只需定期从您的文件中删除所有 *******。 "overwrite data-to-be-deleted with ****" - 如果文件是二进制文件,并且已经有 ***s 表示不同的东西怎么办?此外,这仍然不能提供有效的插入。以上是关于添加和删除文件以不完全重写文件的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中从文件末尾读取的最有效方法是啥? (解析文件中的最后 128 位)
从 .txt 文件中读取未知大小的整数二维数组的最有效方法是啥?