Delphi - tfilestream:写入文件的时间和日期

时间:2015-04-14 20:48:17

标签: delphi tfilestream

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

问题是:

  1. 时间显示为中文字体
  2. 一遍又一遍地替换同一行
  3. 以下是代码:

        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;
    

    谢谢。

3 个答案:

答案 0 :(得分:2)

通常当您期望拉丁文本,但看到中文文本时,这意味着您正在解释ANSI文本,就好像它是UTF-16一样。从这里我推断你打算写出UTF-16文本,但实际上是写出ANSI文本。这意味着你有一个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版本。并始终明确说明您的目标。

答案 1 :(得分:0)

我对代码有一些改变。

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

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

  3. 看起来你只是记录文字。 TFileStream可能不是最好的类。

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

    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

答案 2 :(得分:0)

这个怎么样:

uses SysUtils;

var s: AnsiString;

s := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
fs.Write(s[1], Length(s));