【发布时间】:2019-01-31 12:53:26
【问题描述】:
我有一些文本文件需要能够即时写入,而且经常写入。这些文件可能会变得非常大,但其中的文本在两次迭代之间可能会完全不同。
这意味着文本可以比以前更短。如果我不先清除旧数据,最终会在我的新数据末尾附加旧数据。如 MSDN 文档所示。
如果用较短的字符串(例如“Second run”)覆盖较长的字符串(例如“This is a test of the OpenWrite method”),文件将包含字符串的混合(“Second runtest of OpenWrite 方法”)。
但是文档没有指定补救甚至防止这种情况发生的方法。
目前我正在做以下事情:
File.WriteAllText(path, string.Empty);
using (Stream file = File.OpenWrite(path))
{
file.Write(dataToWrite, 0, dataToWrite.Length);
}
我使用File.WriteAllText(path, string.Empty) 清空现有文件的内容,然后将新内容写入文件。
但是,必须检查整个文件两次感觉很浪费(首先清除它,然后将新数据写入其中)。
有没有一种方法可以用我的新数据覆盖旧数据,只检查“剩余”数据并清除它,而不用两次检查整个文件?
不一定非要使用Stream.Write。任何可以完成工作且速度更快的替代方案都是可以接受的。
结果
在不同的机器上运行 5 次写入 2441 kb 数据(并清除所有旧数据)的 100.000 次迭代后,得出以下结果:
- 我在上面找到的原始方法平均采用
4.75589 ms。 - Anderson Pimentel 的 answer 使用
WriteAllBytes平均得到4.28946 ms。 -
最快 Dark Falcon 的answer 使用
file.Write并截断平均使用4.14433 ms(并且是最快/最一致的)。 -
File.Delete旧文件和使用FileStream.Write创建新文件平均占用5.31883 ms。 - MeJustAndrew 的 answer 执行上述操作,但多线程平均占用了
8.12726 ms。 (虽然我不得不承认这很可能是因为我的执行不力,但我在多线程方面的经验并不丰富)
请注意,这些结果适用于 my implementation 和硬件。结果可能因不同的硬件而异。
【问题讨论】:
-
您是否尝试过将性能与 File.Delete 进行比较并重新创建一个新文件来写入所有文本?这是个有趣的问题。我会想象在编写所有文本时可以选择覆盖整个文件:)
-
File.WriteAllBytes 应该在一行中做你想做的事情。
-
@Joe 谢谢!我不知道
WriteAllBytes也是一个东西。它看起来更干净并且它更快。运行一个小型测试用例,下载一个 6.5mb 的文本文件,它实际上已经快了 2 毫秒(105 毫秒对 103 毫秒)。 (我看到安德森刚刚编辑了他的答案以使用 Bytes aswel) -
@remy_rm 你可以接受 Anderson Pimentel 的回答。
-
@Joe 虽然它在小规模上看起来更快,但在处理更大的文件时实际上看起来性能较差。我在原始问题中包含了一个测试用例。
标签: c# performance file