0

我正在尝试为每个事件保存一行,其中包含一段文本和发生的时间 + 日期。

问题是:

  1. 时间显示为中文字体
  2. 它一遍又一遍地替换同一行

这是代码:

    uses sysUtils, classes;

function log: Boolean;
var
  fs: TFileStream;
  i : String;
  time : TDateTime;

begin
  i := 'Boss is dead!';
  time := now;
  try
    fs := TFileStream.Create('log.txt', fmCreate or fmOpenWrite);
    fs.Write(PChar(i +TimeToStr(time))^, Length(i +TimeToStr(time)));
    fs.write(i, sizeof(i));   
  finally
    fs.Free; 
  end;

end;

谢谢你。

4

3 回答 3

2

通常当您期望拉丁文本但看到中文文本时,这意味着您正在将 ANSI 文本解释为 UTF-16。由此我推断您打算写出 UTF-16 文本,但实际上是写出 ANSI 文本。这意味着你有一个 pre-Unicode Delphi。

至于你为什么继续覆盖文件,那是因为你通过了fmCreate. 您真正想要做的是以写入模式打开现有文件,或者如果不存在文件,则创建一个新文件。Win32 API 函数支持OPEN_ALWAYS创建配置。但这不能通过TFileStream.Create. 所以你必须直接使用THandleStream和调用CreateFile。请注意,较新版本的 Delphi 引入TFile.Open了公开OPEN_ALWAYS功能。但我的推理是你使用的 Delphi 太旧了。

假设您可以使用THandleStream, 并CreateFile正确调用,那么您只需要写出 UTF-16 文本。最简单的方法是使用WideString. 你可以这样写代码:

var
  ws: WideString;
....
Stream.Seek(0, soFromEnd);
ws := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(ws)^, SizeOf(WideChar)*Length(ws));

另一方面,也许中国人来自这里:

fs.write(i, sizeof(i));

这段代码只是写了一个指向文件的指针。您肯定不想这样做,应该删除该行。为了完整起见,如果您确实有 Unicode Delphi,那么您将以非常相似的方式编写文本。像这样:

var
  s: string;
....
Stream.Seek(0, soFromEnd);
s := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(s)^, SizeOf(WideChar)*Length(s));

回到附加到流中,它将像这样运行:

var
  hFile: THandle;
....
hFile := CreateFile(
  PChar(LogFileName),
  GENERIC_WRITE,
  FILE_SHARE_READ,
  nil,
  OPEN_ALWAYS,
  FILE_ATTRIBUTE_NORMAL,
  0
);
Win32Check(hFile<>INVALID_HANDLE_VALUE);
Try
  Stream := THandleStream.Create(hFile);
  Try
    .... code to write to the stream goes here
  Finally
    Stream.Free;
  End;
Finally
  CloseHandle(hFile);
End;

最后,我不得不在这个答案中对你的环境做出很多猜测。将来,请始终包含您使用的 Delphi 版本。并始终包括对您的目标的明确声明。

于 2015-04-14T21:22:14.967 回答
0

这个怎么样:

uses SysUtils;

var s: AnsiString;

s := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
fs.Write(s[1], Length(s));
于 2015-04-15T00:32:04.510 回答
0

关于您的代码,我会更改几件事。

  1. 您有一个应该返回布尔值的函数,但您从未设置返回值。

  2. 这不是“错误”,但变量i最常用作数组的整数索引或循环变量。Delphi 开发人员会讨厌i用作字符串的代码。

  3. 看起来您只是在记录文本。TFileStream 可能不是最好的类。

我认为这是更清晰的代码:

uses System.IoUtils;

...

FileName := 'log.txt';
LogLine  := 'Boss is dead '+TimeToStr(Now);

TFile.AppendAllText(FileName, LogLine);

http://docwiki.embarcadero.com/Libraries/XE7/en/System.IOUtils.TFile.AppendAllText

于 2015-04-14T21:29:37.347 回答