【问题标题】:StreamWriter not writing out the last few characters to a fileStreamWriter 没有将最后几个字符写入文件
【发布时间】:2011-04-22 12:52:05
【问题描述】:

我们在一台服务器上遇到了问题,它使用了 StreamWriter 类。有没有人遇到过类似下面的问题?如果是这样,解决此问题的解决方案是什么?

  using( StreamWriter logWriter = File.CreateText( logFileName ) )
  {
    for (int i = 0; i < 500; i++)
      logWriter.WriteLine( "Process completed successfully." );
  } 

当写出文件时,会生成以下输出:

  Process completed successfully.
  ...  (497 more lines)
  Process completed successfully.
  Process completed s

尝试在没有任何帮助的情况下在关闭之前添加 logWriter.Flush()。我写的文本行越多,数据丢失就越多。

【问题讨论】:

  • 与您的问题无关,但对 Close 的调用是多余的...... StreamWriter 无论如何都会在 using 块的末尾进行处理
  • 是的,更新了帖子并删除了该行。谢谢!
  • 没有人会编写这样的日志记录方法。它会覆盖以前记录的行。代码真的是什么样子的?
  • 你能用你发布的一小段代码重现它吗?你不是——在真实的应用程序中——从多个线程访问流吗?

标签: c# iostream


【解决方案1】:

我自己也有类似的问题。我发现如果我在对流进行任何写入之前启用 AutoFlush 并且它开始按预期工作。 logWriter.AutoFlush = true;

【讨论】:

  • 这完美地解决了我的问题。可能只是修复了 OP 提出问题的那个。
  • 这解决了我的问题的原因:我的 StreamWriter 在完成推出最后几行之前被扫荡 [因为它的调用者超出了范围]。
【解决方案2】:

有时即使你调用flush(),它也不会起到神奇的作用。因为 Flush() 将导致流写入流中的大部分数据,除了其缓冲区的最后一个块。

try
{
 // ... write method
 // i dont recommend use 'using' for unmanaged resource
}
finally
{
 stream.Flush();
 stream.Close();
 stream.Dispose();
}

【讨论】:

  • 针对我遇到的相同问题的出色解决方案。谢谢@Bonshington
【解决方案3】:

无法重现。

在正常情况下,这不应该也不会失败。

  • 这是失败的实际代码吗?文本“过程完成”表明它是一个摘录。
  • 涉及任何线程?
  • 网络驱动器还是本地驱动器?
  • 等。

【讨论】:

  • 经过我们几个人的大量挖掘,我们得出的结论是,这种截断是由于对网站的动态内容启用压缩造成的。我们已经能够在本地重新创建截断问题,并且当我们禁用压缩时它消失了。
【解决方案4】:

这对我来说肯定是一个“刷新”问题,即使您说您添加了对 Flush() 的调用。问题可能在于您的 StreamWriter 只是底层 FileStream 对象的包装器。

我通常不使用 File.CreateText 方法来创建用于写入文件的流;我通常创建自己的 FileStream,然后根据需要用 StreamWriter 包装它。无论如何,我遇到了需要在 StreamWriter 和 FileStream 上调用 Flush 的情况,所以我想这是你的问题。

尝试添加以下代码:

            logWriter.Flush();
            if (logWriter.BaseStream != null)
                logWriter.BaseStream.Flush();

【讨论】:

  • 我也是这么想的,但是StreamWriter 正在刷新其Dispose 中的底层流。
【解决方案5】:

就我而言,这是我在输出文件中发现的

案例 1:没有 Flush() 和没有 Close()

字符长度 = 23,371,776

案例 2:使用 Flush() 而没有 Close()

logWriter.flush()

字符长度 = 23,371,201

案例 3:关闭时

logWriter.Close()

字符长度 = 23,375,887(必需)

所以,为了得到正确的结果,总是需要关闭 Writer 实例。

【讨论】:

    【解决方案6】:

    我遇到了同样的问题

    以下对我有用

    using (StreamWriter tw = new StreamWriter(@"D:\Users\asbalach\Desktop\NaturalOrder\NatOrd.txt"))
    {
        tw.Write(abc.ToString());// + Environment.NewLine);
    }
    

    【讨论】:

    • 这里有什么解决方法?
    【解决方案7】:

    使用框架 4.6.1 并在压力很大的情况下仍然存在此问题。我不确定它为什么会这样,尽管我找到了一种非常不同的解决方法(这加强了我的感觉,它确实是一个 .net 错误)。

    就我而言,我尝试将巨大的锯齿状数组写入磁盘(视频缓存)。 由于锯齿状数组非常大,它必须进行大量重复写入来存储大量视频帧,尽管它们未压缩并且每个缓存文件都有精确的 1000 帧,但记录的现金文件具有不同的大小。

    我用这个的时候遇到了问题

    //note, generateLogfileName is just a function to create a filename()
    
    using (FileStream fs = new FileStream(generateLogfileName(), FileMode.OpenOrCreate))
    {
      using (StreamWriter sw = new StreamWriter(fs)
      {
        // do your stuff, but it will be unreliable
      }
    }
    

    但是,当我为其提供编码类型时,所有记录的文件大小都相同,问题就消失了。

    using (FileStream fs = new FileStream(generateLogfileName(), FileMode.OpenOrCreate))
      {
        using (StreamWriter sw = new StreamWriter(fs,Encoding.Unicode))
        {
          // all data written correctly,  no data lost.
        }
     }
    

    注意还要读取文件宽度相同的编码类型!

    【讨论】:

      【解决方案8】:

      这对我有用:

      streamWriter.flush();
      

      【讨论】:

      • 任何额外的解释都会改善你的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-21
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 2011-08-26
      相关资源
      最近更新 更多