首页 > 解决方案 > 多个 TFileStreams,TStreamWriter 写入同一个文件

问题描述

我开始使用TFileStreamandTStreamWriter来编写简单的文本日志文件(而不是 old Writeln(T,....))。而且我有多个应用程序写入同一个日志文件。每个应用程序当然都有自己TFileStream的,他们每个人都像这样打开文件

FFileStream:=TFileStream.Create(LogName, fmOpenReadWrite+fmShareDenyNone)
FExporter:=TStreamWriter.Create(FFilestream, TEncoding.UTF8);
FExporter.NewLine:=#$0A;
FExporter.AutoFlush:=TRUE;

并写入文件

  FExporter.BaseStream.Seek(0, soFromEnd);
  FExporter.Write('['+DateToStr(Now, FDateTimeFormat)+'] ['+TimeToStr(Now, FDateTimeFormat)+'] [#'+Lead0(GetCurrentThreadId, 5)+']: '+EntryText);
  FExporter.WriteLine;

结果有点“令人不满意”,因为线条被移位,中间的空线条似乎不起作用。

我将如何正确地做到这一点?

标签: delphidelphi-10.3-rio

解决方案


在多个进程中同时写入多行可能会导致意外的继续,因为并行执行。

您应该确保您正在不断地写入一个块,因此应该在最后使用 lineBreak 将 WriteLine 发送到写入内部。

所以你可以写的方式应该是:

  FExporter.BaseStream.Seek(0, soFromEnd);
  FExporter.Write('['+DateToStr(Now, FDateTimeFormat)+'] ['+TimeToStr(Now, FDateTimeFormat)+'] [#'+Lead0(GetCurrentThreadId, 5)+']: '+EntryText + System.slineBreak);
  //FExporter.WriteLine;

更新1: 正如奥利弗发布的链接,如果要写入的消息大小大于操作系统文件扇区,有时它无法工作,此时其他进程也尝试写入消息。因此,在这种情况下,结果内容可能是混合的。

因此,按照我的首要目的,您会增加获得预期结果的可能性,但在 100% 的情况下可能不是解决方案。

为了 100% 确保在单个文件中写入连续日志,使用多个进程,您应该创建一个日志进程来接收来自其他进程的消息,并且是唯一负责在整个线程中写入同步日志的人。


推荐阅读