2016-04-13 53 views
0

我使用在Parallels VM中运行的Delphi XE2和Win10。我创建该文件是这样的:TFilestream写入给出了意想不到的结果

logfile := TFilestream.Create(WRITE_PATH + 'Log.txt', fmCreate); 

这是写:

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'。我想摆脱这一点。 '返回'行是在另一个过程中产生的。花在寻找答案上的时间显示没有解决方案,甚至是另一个例子。也许我搜索了错误的单词。

Line #: -3 
Sending MN050;Line #: -3 
Sending DS;Line #: -3 
Returned [email protected] in 168.5584 

改变的代码:

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; 

结果:

Line #: -3 
Sending MN050; 
Sending DS; 
Sending DS;Returned [email protected] in 183.1767 

Line #: -4 
Sending MN072;DS; 
Returned [email protected]@@@@[email protected] in 175.8367 

Line #: -5 
Sending MN026; 
Sending DS; 
Returned [email protected]@@03539 in 175.4539 
+0

你能表现出[MCVE ]。这个代码也很笨拙。你真的需要把自己提升到更高的层次。你应该有一个类,你可以发送字符串,并让他们登录。相反,你似乎有一个邪恶的UI代码和文件处理代码组合。 –

+0

谢谢你。你能告诉我为什么我的代码不符合最小的,完整的,可验证的标准吗?虽然我同意一个班会是一个改进,但我不知道如何单独解决我的问题。 – Mike

+1

在附注中,您应该考虑直接使用'TStreamWriter'而不是'TFileStream'。 'TStreamWriter'可以封装'TFileStream'(甚至在内部创建一个),并且具有接受标准的'String'值作为输入的'WriteLine()'方法,并且可以在其输出中将它们写为UTF-8。 –

回答

4

它SEMS你曲解日志的内容,它是怎么写的。 到过程结果的第一个调用在

Line #: -3<CRLF> 
Sending MN050; 

(I加入<CRLF>以指示新行字符)

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

Line #: -3<CRLF> 
Sending MN050;Line #: -3<CRLF> 
Sending DS; 

第三个电话再串接到以前

Line #: -3<CRLF> 
Sending MN050;Line #: -3<CRLF> 
Sending DS;Line #: -3<CRLF> 
Returned [email protected] in 168.5584 

结束的第二行也许你的意图是有这样的事情:

Line #: -3 Sending MN050;<CRLF> 
Line #: -3 Sending DS;<CRLF> 
Line #: -3 Returned [email protected] in 168.5584<CRLF> 

,您可以通过从

01移动 + #13#10 实现
str := 'Line #: ' + intToStr(GridLine) + #13#10; 

sx := UTF8String(sToLog + #13#10); 
+0

感谢所有的回应者,这个想法是去除组中所有'Line#'事件,除了最初的一个组合外,请看 – Mike

3

你不经过sToLog字符串添加#13#10 CRLF序列,因此未来Line #:转到同一行。 可能修正

str := sToLog + #13#10; 
len := 0; 
sx := UTF8String(str); 

,但你最好重写这段代码到独立的函数或方法与网格线和sToLog参数

+0

谢谢在那里添加一个CRLF给了我 – Mike

3

正如其他人说,你是不是第二个行之后写一个换行符,所以未来日志消息的第一行会被附加到前一条日志消息的第二行。所以你需要在正在写入的第二行添加换行符。

我建议你改变你的代码直接使用TStreamWriter而不是TFileStream

logfile := TStreamWriter.Create(WRITE_PATH + 'Log.txt', False, TEncoding.UTF8); 

如果您希望日志是这样的:

线#:-3
发送MN050;
行号:-3
发送DS;
行#:如果您希望日志这个样子,而不是

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
返回DSANT = ATV @在168.5584

然后,你可以这样做

行号:-3发送MN050;
行号:-3发送DS;
行#:在168.5584

-3回国DSANT = ATV @然后,你可以这样做:

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; 

或者简单:

procedure TfrmMain.Logit(const sToLog: string); 
begin 
    if mnuMain.Items[1].Items[2].Checked then 
    logfile.WriteLine('Line #: %d %s', [GridLine, sToLog]); 
end; 
相关问题