首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi - tfilestream:将时间和日期写入文件

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

Stack Overflow用户
提问于 2015-04-14 20:48:16
回答 3查看 2.4K关注 0票数 0

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

问题是:

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

以下是代码:

代码语言:javascript
复制
    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;

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-14 21:22:14

通常,当你期待拉丁文,但看到中文文本,这意味着你解释ANSI文本,好像它是UTF-16。由此我推断,你打算写出UTF-16文本,但实际上是写ANSI文本。这意味着你有一个预Unicode德尔菲。

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

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

代码语言:javascript
复制
var
  ws: WideString;
....
Stream.Seek(0, soFromEnd);
ws := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(ws)^, SizeOf(WideChar)*Length(ws));

另一方面,也许中国人是从这里来的:

代码语言:javascript
复制
fs.write(i, sizeof(i));

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

代码语言:javascript
复制
var
  s: string;
....
Stream.Seek(0, soFromEnd);
s := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(s)^, SizeOf(WideChar)*Length(s));

回到附加到流的后面,它会像这样运行:

代码语言:javascript
复制
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版本。并且总是明确地陈述你的目标。

票数 2
EN

Stack Overflow用户

发布于 2015-04-14 21:29:37

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

  1. 您有一个应该返回布尔值的函数,但是您从不设置返回值。
  2. 这不是“错误”,但变量i最常用作数组的整数索引或循环变量。developers将讨厌使用i作为字符串的代码。
  3. 看起来你只是在记录短信。TFileStream可能不是这样做的最好的类。

我认为这是一个更干净的代码:

代码语言:javascript
复制
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

票数 0
EN

Stack Overflow用户

发布于 2015-04-15 00:32:04

这个怎么样:

代码语言:javascript
复制
uses SysUtils;

var s: AnsiString;

s := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
fs.Write(s[1], Length(s));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29637128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档