【问题标题】:TStreamWriter (Auto)Flush does not?TStreamWriter (Auto)Flush 没有?
【发布时间】:2014-01-06 15:30:51
【问题描述】:

尽管在Text File Writing performances in Delphi(Ken White 的回答下的 cmets)中说了些什么,我看到 TStreamWriter not 使用以下代码刷新:

procedure TFrmAddEvents.LogEvent(AEvent: TcxSchedulerEvent);
begin
   if not Assigned(FStreamWriter) then
   begin
      FStreamWriter := TStreamWriter.Create(TFileStream.Create(ChangeFileExt(ParamStr(0),'.log'),fmCreate or fmOpenRead));
      FStreamWriter.AutoFlush := true;
   end;
   FStreamWriter.WriteLine(TcxEventDescription(AEvent));
   // Even this has no effect:
   FStreamWriter.Flush;
end;

即使在执行之后

if Assigned(FStreamWriter) then FStreamWriter.Free;    

在 FormClose 中,文件仍然是 0 字节。
程序执行完毕后,文件大小为 600+ kB。

  • FStreamWriter 是 TStreamWriter 类型的表单属性。
  • 使用fmCreate or fmOpenWrite 创建没有区别。
  • TcxEventDescription 确实给出了一个有效的返回字符串 > 500 字节,其中包含 CRLF。
  • 如您所见,我没有对编码做任何事情,所有默认的 Unicode 东西。
  • 我从 Delphi XE2 IDE 运行或作为独立的可执行文件运行。
  • Win7 64位下的32位应用

会发生什么以及如何解决?

[2014 年 1 月 7 日编辑]

Uwe 回答后更新代码;还是不行:

procedure TFrmAddEvents.LogEvent(AEvent: TcxSchedulerEvent);
var lName: string;
begin
   lName := ChangeFileExt(ParamStr(0),'.log');
   if not Assigned(FStreamWriter) then
   begin
      FStreamWriter := TStreamWriter.Create(lName); // Or TStreamWriter.Create(lName,true);
      FStreamWriter.AutoFlush := true;
   end;
   FStreamWriter.WriteLine(TcxEventDescription(AEvent));
   // Next does not help either:
   FStreamWriter.Flush;
end;

在我调用 FStreamWriter.Free 之前,文件仍然为 0 字节。

【问题讨论】:

  • 注意 StreamReader/StreamWrite 也支持 OwnStream 来拥有 Stream,否则默认情况下,当流传递给他们的构造函数时,他们不会拥有它

标签: delphi delphi-xe2


【解决方案1】:

TStreamWriter 刷新意味着它只会将其缓冲区写入附加的流。这并不一定意味着任何 TFileStream 都会刷新其 OS 缓冲区,只是因为 TStreamWriter 不知道任何 TFileStream(仅 TStream)。

更糟糕的是,您提供了一个您自己创建的 TFileStream 实例。所以 TStreamWriter 不获取流的所有权,因此不会在 Destroy 上释放它。然而,流的释放将关闭文件,从而将内容写入磁盘。

【讨论】:

  • 是的,我刚刚想通了,但你写得比我快。 :-) 我已经回去更新链接的帖子以使用不同的构造函数,将TFileStream 的所有权授予TStreamWriter。还阐明了AutoFlush 的工作方式。
  • 有趣。既然你写了这个 - 当然。但是,它仍然没有冲洗。我现在有 TStreamWriter.Create(filename) 并且文件在 TStreamWriter.Free 之前保持 0 字节。没有 AutoFlush 或 Flush 帮助。
  • 这是因为内部文件流自己缓冲。流编写器对此没有影响。如果你想要一个无缓冲的文件流,你必须编写你自己的实现。
  • 这让我们想回到老式的 TTextFile I/O。它仅用于日志记录/调试目的,我想确保在程序挂起之前我的日志信息全部刷新到磁盘。 XE2 是否有更现代的文件/流对象可以让我轻松做到这一点?
  • 如果仅用于日志记录/调试,我建议使用 CodeSite。
猜你喜欢
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多