Forum > General

TFileStream.ReadAnsiString/WriteAnsiString. Non-printable characters in files

(1/2) > >>

I want to read/write some information in a text file using TFileStream.ReadAnsiString/WriteAnsiString.

The drawback I encountered with this methods is that the generated files have the first 4 bytes with the length of every string that is read/written (as in documentation).

This implies that the generated files are not purely textual, having non-printable characters corresponding to the bytes that encode the length of strings.

Is there a way to overcome this inconvenience? Thanks in advance.

If you want to use ReadAnsiString then these 4 bytes are required, otherwise you wouldnt know how long is the string, and there can be multiple strings.

Use other methods, Read/Write or ReadBuffer/WriteBuffer.


--- Quote from: simone on November 28, 2023, 01:40:16 pm ---I want to read/write some information in a text file using TFileStream.ReadAnsiString/WriteAnsiString.

--- End quote ---
You're not treating that file as a text file then.
If you want it to be a text file, treat it as a text file.
Either use the TextFile type for the file and use read(ln)/write(ln), use a TStringList and use it's LoadFromFile/SaveToFile methods, or treat it as an untyped file and read into a buffer, parse the buffer, make changes, write the new buffer back to the file.
I personally would not advice the last one though.


Yes, I know how to deal with text files, with the classic approach or with TStringList methods. In my context, I want to use streams because I need to save text files both in files and in memory. Streams, as well known, allow this type of needs to be managed in a unified way.

Since TStream.WriteAnsiString is virtual, while TStream.ReadAnsiString is not (why???), I can't override them to change their behavior. So, using class helpers, I devised this simple solution to manage purely textual (ansi) files with streams:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1;uses  Classes; type   { TStreamHelper }   TStreamHelper=class helper for TStream    function ReadText:string;    procedure WriteText(const Text : string);  end;  var  FileStream : TFileStream; { TStreamHelper } function TStreamHelper.ReadText:string;var  P : PByte;begin  Result:='';  SetLength(Result,Size);  Position:=0;  ReadBuffer(Pointer(Result)^,Size);  P:=Pointer(Result)+Size;  P^:=0;end; procedure TStreamHelper.WriteText(const Text : string);begin  Position:=0;  WriteBuffer(Pointer(Text)^,Length(Text));end; begin  //write test  FileStream:=TFileStream.Create('file.txt',fmCreate);  try    FileStream.WriteText('aaabbbccc');  finally    FileStream.Free;  end;   //read test  FileStream:=TFileStream.Create('file.txt',fmOpenRead);  try    writeln(FileStream.ReadText);  finally    FileStream.Free;  end;   readln;end.


--- Quote from: simone on November 28, 2023, 11:10:37 pm ---I need to save text files both in files and in memory.
--- End quote ---
Where do you think goes the data of a loaded TStringList when not in memory?
And for your code I suggest to use AnsiString/PAnsiChar type to be future compatible and to inform users of your code, what it really is compatible with.


[0] Message Index

[#] Next page

Go to full version