【问题标题】:Writing to txt file with StreamWriter and FileStream使用 StreamWriter 和 FileStream 写入 txt 文件
【发布时间】:2013-02-02 01:22:57
【问题描述】:

我在使用 StreamWriterFileStream 将文本附加到 .NET 4.5 中的现有文件时遇到了一些有趣的事情(没有尝试过任何旧框架)。我尝试了两种方法,一种有效,一种无效。我想知道这两者有什么区别。

这两种方法都在顶部包含以下代码

if (!File.Exists(filepath))
    using (File.Create(filepath));

我在using 声明中创建,因为我通过个人经验发现这是确保应用程序完全关闭文件的最佳方式。

非工作方式:

using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write))
    (new StreamWriter(f)).WriteLine("somestring");

使用此方法最终不会将任何内容附加到文件中。

工作方法:

using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write))
    using (StreamWriter s = new StreamWriter(f))
        s.WriteLine("somestring");

我做了一些谷歌搜索,不太清楚要搜索什么,也没有找到任何有用的信息。那么,为什么匿名StreamWriter 在(非匿名?命名?)StreamWriter 起作用的地方失败了?

【问题讨论】:

  • 我猜StreamWriter 在刷新之前实际上并没有 write 任何东西,它的 Dispose 方法通过与 using 块一起使用而被隐式调用会自动冲洗它。编辑:请注意StreamWriter 有一个AutoFlush 属性,它可以控制这种行为,让它在你写的时候自动刷新流,我猜默认是false
  • 这已经被回答了,但是你为什么要这样格式化代码呢?阅读和理解 IMO 非常可怕,而且通过简单的格式错误引入错误的风险也会增加。我是牙套的忠实粉丝 - 永远!
  • @TheCodeKing 如果已经回答,您介意提供链接吗?我诚实地寻找它并在发布之前查看了每个建议的答案,但没有看到任何可以完全回答它的东西(主要是因为我使用了匿名函数。)另外,我不是在这里讨论最重要的事情部分风格和基于偏好。杂乱无章的大括号的 IMO 代码更难阅读。
  • @TheCodeKing 但我也在 Python 中做了很多工作,因此使用缩进来确定范围已成为第二天性。
  • 这里提到msdn.microsoft.com/en-us/library/…,如果未设置 AutoFlush,则在关闭时刷新。当 Dispose 关闭流时,您需要显式调用 Dispose 或 Close 来刷新流。

标签: c#


【解决方案1】:

听起来你没有刷新流。

http://msdn.microsoft.com/en-us/library/system.io.stream.flush.aspx

看起来 StreamWriter 在写入最终目标(在本例中为文件)之前先写入缓冲区。您还可以设置 AutoFlush 属性,而不必显式刷新它。

http://msdn.microsoft.com/en-us/library/system.io.streamwriter.autoflush.aspx

为了回答您的问题,当您使用“using”块时,它会调用 StreamWriter 上的 dispose,而后者又必须调用 Flush。

【讨论】:

  • 您永远不应该创建实现 IDisposable 的类型的匿名实例。
  • 我不建议使用 AutoFlush 并且不处理对象。如果一个对象是一次性的,它应该被丢弃。
  • 我同意所有评论者的观点,他们认为您应该始终处理一次性物品。另外,我想回复 Leon 的试看评论,并说除非明确要求,否则永远不会释放对象。但是,如果它们有终结器,它们就会被终结。
  • @PhillipScottGivens 确实如此,但依赖终结器并不是一个好习惯。您不知道它何时会运行,因此您不知道该资源将存在多长时间。
  • @PhillipScottGivens 在这段时间之后不要试图把它带回来,但我今天重读了这个问题,发现当StreamWriter 使用@987654325 初始化时,实际上可以设置AutoFlush @ 仍然不是最佳实践,但它是另一种可行且有效的解决方案。
【解决方案2】:

两个代码sn-ps的区别在于using的使用。 The using statement 将对象放置在块的末尾。

StreamWriter 在将数据写入底层流之前对其进行缓冲。处理 StreamWriter 会刷新缓冲区。如果您不刷新缓冲区,则不会写入任何内容。

来自MSDN

您必须调用 Close 以确保所有数据都正确写入底层流。

另见:When should I use “using” blocks in C#?

【讨论】:

  • 不要感到痛苦,因为我或多或少已经假设了这一点,但是您是否可以添加一些参考资料,说明我可以在网上找到这些信息的地方?这是为了他人的利益,也是为了我自己的利益。
猜你喜欢
  • 2013-11-02
  • 2015-05-07
  • 1970-01-01
  • 2012-01-17
  • 2014-02-22
  • 2018-08-24
  • 2014-08-14
  • 1970-01-01
  • 2016-05-03
相关资源
最近更新 更多