I am trying to save a line for each event containing a piece of text and the time + date when happened.
The problem is:
Here is the code:
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;
Thank you.
Usually when you expect Latin text, but see Chinese text, that means that you are interpreting ANSI text as though it were UTF-16. From this I infer that you are intending to write out UTF-16 text, but are actually writing out ANSI text. Which means that you have a pre-Unicode Delphi.
As far as why you keep overwriting the file, then that's because you pass fmCreate
. What you really want to do is open an existing file in write mode, or if no file exists, create a new file. The Win32 API function supports that with the OPEN_ALWAYS
creation disposition. But that is not available through TFileStream.Create
. So you have to use THandleStream
and call CreateFile
directly. Note that newer versions of Delphi introduce TFile.Open
that exposes OPEN_ALWAYS
functionality. But my reasoning says you are using a Delphi that is too old.
Assuming that you can use THandleStream
, and call CreateFile
correctly, then you just need to write out UTF-16 text. The simplest way is to use a WideString
. You might write the code like this:
var
ws: WideString;
....
Stream.Seek(0, soFromEnd);
ws := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(ws)^, SizeOf(WideChar)*Length(ws));
On the other hand, perhaps the Chinese comes from here:
fs.write(i, sizeof(i));
This code simply writes a pointer to the file. You for sure don't want to do that and should remove that line. For sake of completeness, if you do have a Unicode Delphi, then you would write the text in a quite similar way. Like this:
var
s: string;
....
Stream.Seek(0, soFromEnd);
s := TimeToStr(Now) + sLineBreak;
Stream.WriteBuffer(PWideChar(s)^, SizeOf(WideChar)*Length(s));
Going back to appending to a stream, that would run like this:
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;
Finally, I have had to make a lot of guesses about your environment in this answer. In future, always include the Delphi version that you use. And always include a clear statement of your goals.