delphi - 多个 TFileStreams,TStreamWriter 写入同一个文件
问题描述
我开始使用TFileStream
andTStreamWriter
来编写简单的文本日志文件(而不是 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;
结果有点“令人不满意”,因为线条被移位,中间的空线条似乎不起作用。
我将如何正确地做到这一点?
解决方案
在多个进程中同时写入多行可能会导致意外的继续,因为并行执行。
您应该确保您正在不断地写入一个块,因此应该在最后使用 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% 确保在单个文件中写入连续日志,使用多个进程,您应该创建一个日志进程来接收来自其他进程的消息,并且是唯一负责在整个线程中写入同步日志的人。
推荐阅读
- javascript - 在使用 javascript 函数过滤掉某些行后,如何将 CSS 应用于奇数/偶数可见行?(错误地标记为重复)
- javascript - 当我们在javascript中将字符串变量初始化为null或空字符串时有什么区别?哪个是首选
- c++ - 由于 X509 重新定义问题,编译 WebRTC 和 boost::uuid 时出现问题。我应该在哪里创建问题?
- google-sheets - 如果另一个单元格的值为零,是否有一个公式可以用来返回 0 值?
- r - 使用数据框中的因子名称和级别顺序的变量更改 R 中的因子级别
- scala - Scala 中 TypedDataset 和类型边界的隐式编码器
- selenium - 获取以下代码的“元素不可交互”
- python - 在 TensorFlow 中沿一个轴应用排列
- angular - 为什么 ng serve 会导致 JS 文件出现 404 错误?
- android - 从相机意图中获取像素的颜色