在移植到Unicode和Delphi 2009之前,我有一些代码会逐行将文本附加到日志文件中:
procedure AppendToLogFile(S: string);
// this function adds our log line to our shared log file
// Doing it this way allows Wordpad to open it at the same time.
var F, C1 : dword;
begin
if LogFileName <> '' then begin
F := CreateFileA(Pchar(LogFileName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0);
if F <> 0 then begin
SetFilePointer(F, 0, nil, FILE_END);
S := S + #13#10;
WriteFile(F, Pchar(S)^, Length(S), C1, nil);
CloseHandle(F);
end;
end;
end;
但是CreateFileA和WriteFile是二进制文件处理程序,不适用于Unicode。
我需要找到一个能够在Delphi 2009下执行相应操作并处理Unicode的工具。
我之所以为每一行都打开、写入、关闭文件,只是为了让其他程序(如WordPad)在日志写入时可以打开文件并读取它。
我一直在尝试使用TFileStream和TextWriter,但是它们的文档很少,示例也很少。
具体来说,我不确定它们是否适合这种不断打开和关闭文件的操作。此外,我也不确定它们是否可以在写入文件时使文件可供阅读。
有人知道我该如何在Delphi 2009或更高版本中实现这个操作吗?
结论:
Ryan的答案是最简单的,也是导致我找到解决方案的答案。使用他的解决方案,您还需要编写BOM并将字符串转换为UTF8(如我在他的答案中的评论中所述),然后就可以正常工作了。
但是我又更进一步研究了TStreamWriter。它是同名.NET函数的等效物。它理解Unicode,并提供非常干净的代码。
我的最终代码是:
procedure AppendToLogFile(S: string);
// this function adds our log line to our shared log file
// Doing it this way allows Wordpad to open it at the same time.
var F: TStreamWriter;
begin
if LogFileName <> '' then begin
F := TStreamWriter.Create(LogFileName, true, TEncoding.UTF8);
try
F.WriteLine(S);
finally
F.Free;
end;
end;
最后,我发现另一个方面就是如果你追加了很多行(比如1000行或更多),那么对文件的追加需要越来越长的时间,并且变得非常低效。
因此,我最终决定不在每次重新创建和释放LogFile。相反,我保持它处于打开状态,这样速度就会非常快。唯一无法做到的事情就是在文件被创建时允许使用记事本查看文件。