2016-04-13 87 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; 
相關問題