我应该先构建字符串再写入文件吗?

3

我现在正在开发的一个程序需要生成一个文件。是先将文件内容作为字符串生成,然后再将该字符串写入文件,还是直接将内容添加到文件中,哪种方法更好呢?

这两种方法有没有优劣之分呢?

该文件大小约为0.5-1MB。


“将文件的内容生成为字符串”是什么意思? - Rahul
基本上,我有一个巨大的字典需要按照特定格式转换为文件,并且其中很大一部分是硬编码的。因此,我在想是否应该边进行写入操作,还是先将所有内容写入 StringBuilder 中,然后在完成后将 StringBuilder 内容写入文件。 - Ayush
3个回答

9

如果你边写边读文件,当处理的文件足够大并且经常清空缓存流时,你可以受益于不将所有数据保留在内存中。

然而,这种方式可能会遇到部分文件已被写入但未完成的问题,因为你是在一段时间内进行IO操作,而不是一次性进行。

个人建议使用StringBuilder逐渐构建整个内容,然后一次性写入磁盘中。


3
如果一个部分写入的文件是一个问题,一种选择是先写入一个临时文件,当文件准备好后,将其移动到预定位置。这样你既可以避免在内存中存储过多内容,同时又确保生成的文件是一致的。 - Fredrik Mörk
1
以单个操作写入文件仍可能导致部分写入的文件,因此这不应该成为不增量写入的理由。 - Rowland Shaw
@Fredrik - 没错,我喜欢这个方法,不过我会和 StringBuilder 结合使用,因为它可以处理错误。这也提醒了 @Rowland - 你说得没错,但是 1)出错的概率更低,2)针对这种情况的错误处理可以在一个地方完成。 - Jerod Venema
1
我认为在认为如果你以“单个”操作进行磁盘写入,就会显著降低失败风险的想法中存在谬误(部分原因是单个操作很少);关于错误处理,您仍然可以在Save(...)方法中捕获所有这些异常,对吧?所以它仍然是一个单一位置。 - Rowland Shaw
@Rowland,我不同意你的观点。问题中并没有提到必须按顺序执行所有写入操作。如果你有多个对File.Write(...); File.Flush(); [do other stuff]; File.Write(...); File.Flush()的调用,与只在一个地方写入和刷新整个文件相比,我个人认为后者会更容易维护。 - Jerod Venema
感谢您的回答和评论。最终我选择了使用字符串构建器,因为在类中我会用几种不同的方法拼接文件内容,使用一个类数据成员更容易实现。 - Ayush

2

一般情况下,我认为更好的做法是创建一个 StreamWriter 并直接向其写入内容。不必将所有内容存储在内存中,何必增加负担呢?这样做也更加简单方便。例如:

using (var writer = new StreamWriter("filename"))
{
    writer.WriteLine(header);
    // write all your data with Write and WriteLine,
    // taking advantage of composite formatting
}

如果您想使用StringBuilder构建多行文本,您需要编写类似于以下内容的代码:
var sb = new StringBuilder();
sb.AppendLine(string.Format("{0:N0} blocks read", blocksRead));
// etc., etc.
// and finally write it to file
File.WriteAllText("filename", sb.ToString());

当然还有其他选项。你可以将这些行构建成一个List<string>,然后使用File.WriteAllLines。或者你可以写入一个StringStream,然后再将其写入文件。但是所有这些方法都需要你多次处理数据。只需打开StreamWriter并进行写入即可。
我认为直接输出的主要原因如下:
  • 当输出数据太大无法放入内存时,您不必重构代码。
  • 计划的目标是文件,那么为什么不在写入文件之前在内存中格式化它呢?
  • 我认为,将多行文本写入文件的API比向StringBuilder添加行的API更加清晰。

-1
我认为最好使用string或stringbuilder来存储你的数据,这样你就可以使用File.Write函数写入文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接