ANSI text processing (file parsing and creation)


#1

I have to rewrite Delphi code which parses and creates certain file formats (all single byte based) and do not find a multi-platform way to do it. (The code should work on Island, OSX, .NET and Java.)

When I was writing files before I also wrote to the characters of an AnsiString which works very fast with Delphi. The RTL AnsiString class allows writing, but is this effective?
When reading files I was using a memory stream and a pointer into the memory. That obviously does not work anymore.

When I create an array of bytes do I get a buffer with bytes or do I get an array of objects pointing to Byte objects?

Does anybody have a hint to the ideal approach to solve this problem?

Thanks, Julian


(marc hoffman) #2

I’d look at the Binary and Encoding classes in Elements RTL.

Binary will get you red/write the exact bytes from a file to a memory buffer and vice versa. You can then access these as byte array and for other manipulation. Encoding.ASCII will let you treat these buffers as 8-bit strings and convert them to/from platform native strings, to work with the data as string.

Elements has no AnsiString type our se. When working with String as as String type, it will always be 16 bits per character. But the Encoding class will let you read/wrioteb those to/from files in the proper 8-bit format.

hth,
marc


#3

Thanks marc,

i started with a silly experiment to load a stream byte wise into a string. I tried to use the BinaryStream class and tested this as .NET project. But I think I run into an issue I don’t understand.

This code does not work:

  function ReadWrite.LoadFile(filename : String) : String;
  var bin :BinaryStream;
      f : FileStream;
      i : Integer;
      t : StringBuilder;
  begin
      try
          t := new StringBuilder;
          f := new FileStream(filename, FileOpenMode.ReadOnly);
          bin := new BinaryStream(f);

            while true do
            begin
                  i := bin.ReadByte;
                  // this works: i := f.ReadByte;
                  if i>=0 then t.Append(Char(i)) else break;
            end;

            result:=t.ToString;
    except
        result:='Error';
    end;
  end;

In the debugger (VS 2015) the cpu jumps between bin := new BinaryStream and the “Append” line. It never finishes. The code works immediately when I use i := f.ReadByte - I then get the file as a string.


(Friedrich Westermann) #4

Do it like these:

method test;
    begin
      // Create Filestream
      var f := new FileStream('myFile.txt', FileOpenMode.&ReadOnly);
      // Create Textstream
      var t := new TextStream(f, Encoding.ASCII);
      // Get the String
      var s := t.ReadString(f.Length);
    
    end;

#5

Thanks - this looks ideal - my code was just an experiment to try out different ways to do byte reading.


(marc hoffman) #6

Also, this is .NET specific. use Elements RTL, and its Binary class, instead.