首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TFilestream写入产生意外结果

TFilestream写入产生意外结果
EN

Stack Overflow用户
提问于 2016-04-14 03:12:21
回答 3查看 139关注 0票数 0

我使用的是在Parallels虚拟机中运行的Delphi XE2和Win10。我像这样创建这个文件:

代码语言:javascript
复制
logfile := TFilestream.Create(WRITE_PATH + 'Log.txt', fmCreate);

这是这样写的:

代码语言:javascript
复制
procedure TfrmMain.Logit(const sToLog: string);
var
len: cardinal;
ss, sx: UTF8String;
str: string;
begin
if mnuMain.Items[1].Items[2].checked then
begin
    str := 'Line #: ' + intToStr(GridLine) + #13#10;
    ss := UTF8String(str);
    len := length(ss);
    logfile.WriteBuffer(ss[1],len);
    ss := '';    
    str := '';
    len := 0;
    sx := UTF8String(sToLog);
    len := length(sx);
    logfile.WriteBuffer(sx[1], len);
  end;
end;

结果呢。注意‘发送’行上额外的'Line #:-3‘。我想摆脱它。“返回”行是在另一个进程中生成的。花了几个小时寻找答案,没有发现任何解决方案,甚至是另一个例子。也许我搜索错了词。

代码语言:javascript
复制
Line #: -3
Sending MN050;Line #: -3
Sending DS;Line #: -3
Returned DSANT=ATV@ in 168.5584

更改代码:

代码语言:javascript
复制
procedure TfrmMain.Logit(sToLog: string);
var
  len: cardinal;
  ss, sx: UTF8String;
  str: string;
begin
  str := mnuMain.Items[1].Items[2].Caption;
  if mnuMain.Items[1].Items[2].checked then
  begin
    if flag then
    begin
      str := 'Line #: ' + intToStr(GridLine) + #13#10;
      ss := UTF8String(str);
      len := length(ss);
      logfile.WriteBuffer(ss[1],len);
    end;
    flag := false;
    ss := UTF8String('');
    sx := UTF8String(sToLog) + #13#10;
    len := length(sx);
    logfile.WriteBuffer(sx[1], len);
  end;
end;

结果是:

代码语言:javascript
复制
Line #: -3
Sending MN050;
Sending DS;
Sending DS;Returned DSANT=ATV@ in 183.1767

Line #: -4
Sending MN072;DS;
Returned DS@@@@@ON@ in 175.8367

Line #: -5
Sending MN026;
Sending DS;
Returned DS@@@03539 in 175.4539
EN

回答 3

Stack Overflow用户

发布于 2016-04-14 03:55:47

它看起来像是您曲解了日志的内容以及它是如何写入的。对该过程的第一次调用将导致

代码语言:javascript
复制
Line #: -3<CRLF>
Sending MN050;

(我添加了<CRLF>以指示新行字符)

注意,在第二行之后没有<CRLF>。因此,下一个调用将连接到第一个调用的第二行

代码语言:javascript
复制
Line #: -3<CRLF>
Sending MN050;Line #: -3<CRLF>
Sending DS;

第三个调用再次连接到上一个

代码语言:javascript
复制
Line #: -3<CRLF>
Sending MN050;Line #: -3<CRLF>
Sending DS;Line #: -3<CRLF>
Returned DSANT=ATV@ in 168.5584

也许你的意图是拥有这样的东西:

代码语言:javascript
复制
Line #: -3 Sending MN050;<CRLF>
Line #: -3 Sending DS;<CRLF>
Line #: -3 Returned DSANT=ATV@ in 168.5584<CRLF>

这可以通过将+ #13#10

代码语言:javascript
复制
str := 'Line #: ' + intToStr(GridLine) + #13#10;

代码语言:javascript
复制
sx := UTF8String(sToLog + #13#10);
票数 4
EN

Stack Overflow用户

发布于 2016-04-14 03:55:59

您不会在sToLog字符串之后添加#13#10 CRLF序列,因此下一个Line #:将转到同一行。可能的修正

代码语言:javascript
复制
str := sToLog + #13#10;
len := 0;
sx := UTF8String(str);

但最好将此代码重写为具有GridLine和sToLog参数的独立函数或方法

票数 3
EN

Stack Overflow用户

发布于 2016-04-14 07:01:40

正如其他人所说的那样,您不会在第二行之后编写换行符,因此未来日志消息的第一行将被附加到先前日志消息的第二行。因此,您需要在正在编写的第二行中添加一个换行符。

我建议您更改代码,直接使用TStreamWriter而不是TFileStream

代码语言:javascript
复制
logfile := TStreamWriter.Create(WRITE_PATH + 'Log.txt', False, TEncoding.UTF8);

如果您希望日志如下所示:

行号:-3

发送MN050;

行号:-3

发送DS;

行号:-3

在168.5584中返回DSANT=ATV@

然后你可以这样做:

代码语言:javascript
复制
procedure TfrmMain.Logit(const sToLog: string);
begin
  if mnuMain.Items[1].Items[2].Checked then
  begin
    logfile.WriteLine('Line #: ' + IntToStr(GridLine));
    logfile.WriteLine(sToLog);
  end;
end;

如果您希望日志看起来像这样:

线路号:-3发送MN050;

第#行:-3发送DS;

第#行:-3在168.5584中返回DSANT=ATV@

然后你可以这样做:

代码语言:javascript
复制
procedure TfrmMain.Logit(const sToLog: string);
begin
  if mnuMain.Items[1].Items[2].Checked then
  begin
    logfile.Write('Line #: ' + IntToStr(GridLine) + ' ');
    logfile.WriteLine(sToLog);
  end;
end;

或者简单地这么说:

代码语言:javascript
复制
procedure TfrmMain.Logit(const sToLog: string);
begin
  if mnuMain.Items[1].Items[2].Checked then
    logfile.WriteLine('Line #: %d %s', [GridLine, sToLog]);
end;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36607526

复制
相关文章

相似问题

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