Einzelnen Beitrag anzeigen

Ares

Registriert seit: 5. Dez 2002
269 Beiträge
 
#1

Daten aus einem Stream lesen und darstellen

  Alt 18. Feb 2008, 11:45
Hallo!

Ich will Daten aus einer Datei bzw. einem Stream auslesen und wie in einem Hex-Editor darstellen. Ich scheitere aber daran, dass ich nicht weiß, welchen Datentyp ich für die Variable verwenden soll in die die Daten aus dem Stream gelesen werden. Ich habe folgendes Testprogramm geschrieben:

Delphi-Quellcode:
unit main;

...

function ShowBinary(var Data; Count: Cardinal): TStrings;

implementation

{$R *.dfm}

procedure TForm1.readBtClick(Sender: TObject);
var Stream: TStream;
    Data: array of byte;
begin
  Memo1.Lines.Clear;

  setLength(Data, 128);
  Stream := TFileStream.Create('D:\Test.txt', fmOpenRead or fmShareDenyNone);
  Stream.Seek(0, soFromBeginning);
  
  Stream.Read(Data[0], 128); // <-- funktioniert, aber falsche Darstellung
  //Stream.Read(Data, 128); // <-- korrekte Darstellung aber Exception

  Memo1.Lines.AddStrings(ShowBinary(Data, 128));
end;


// ShowBinary stammt von [url]http://www.swissdelphicenter.com/de/showcode.php?id=944[/url]
// Wurde nur leicht modifiziert um TStrings zurück zu geben...
function ShowBinary(var Data; Count: Cardinal): TStrings;
var
  line: string[80];
  i: Cardinal;
  p: PChar;
  nStr: string[4];
const
  posStart = 1;
  binStart = 7;
  ascStart = 57;
  HexChars: PChar = '0123456789ABCDEF';
begin
  result := TStringList.Create;

  p := @Data;
  line := '';
  for i := 0 to Count - 1 do begin
    if (i mod 16) = 0 then begin
      if Length(line) > 0 then
        result.Add(line);
      FillChar(line, SizeOf(line), ' ');
      line[0] := Chr(72);
      nStr := Format('%4.4X', [i]);
      Move(nStr[1], line[posStart], Length(nStr));
      line[posStart + 4] := ':';
    end;

    if p[i] >= ' then
      line[i mod 16 + ascStart] := p[i]
    else
      line[i mod 16 + ascStart] := '.';

    line[binStart + 3 * (i mod 16)] := HexChars[(Ord(p[i]) shr 4) and $F];
    line[binStart + 3 * (i mod 16) + 1] := HexChars[Ord(p[i]) and $F];
  end;
  result.Add(line);
end;
Bei einem Klick auf den Read-Button sollen die ersten 128 Bytes einer Textdatei eingelesen und im Hex-Format angezeigt werden. Die Text Datei enhält folgenden Inhalt:
Zitat:
Test Test Test Test Test Test Test Test Test Test
Test Test Test Test Test Test Test Test Test Test
Test Test Test Test Test Test Test Test Test Test
Test Test Test Test Test Test Test Test Test Test
Test Test Test Test Test Test Test Test Test Test
...
Wenn ich nun "Stream.Read(Data[0], 128);" funktioniert alles ohne Fehler, aber es wird folgender Inhalt angezeigt:
Zitat:
0000: B8 86 DA 00 F4 F5 12 00 FA 8F 43 00 70 0E DE 00 ¸†Ú.ôõ..úC.p.Þ.
0010: 4B 83 42 00 50 F6 12 00 49 84 42 00 70 0E DE 00 KƒB.Pö..I„B.p.Þ.
0020: F2 8A 43 00 50 F6 12 00 58 F8 12 00 70 0E DE 00 òŠC.Pö..Xø..p.Þ.
0030: 08 CB A8 00 D2 39 01 7A A5 C3 83 76 16 B9 83 76 .˨.Ò9.z¥Ãƒv.¹ƒv
0040: D2 39 01 7A 3A 00 00 00 10 F5 12 00 20 00 00 00 Ò9.z:....õ.. ...
0050: 08 F5 12 00 86 2D 84 76 0A 80 00 00 94 F5 12 00 .õ..†-„v.€..”õ..
0060: B1 B5 84 76 0A 80 00 00 5A 12 18 00 FC FF FF FF ±µ„v.€..Z...üÿÿÿ
0070: 00 00 00 00 00 00 00 00 30 F6 12 00 CE 22 85 76 ........0ö..Î"…v
Diese Daten sind nicht in der Datei enthalten und kann mir nicht erklären wo diese herkommen...

Verwende ich hingegen "Stream.Read(Data, 128);" wird eine Exception ausgelöst, aber es wird trotzdem der korrekte Inhalt angezeigt:
Zitat:
Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 004056FC in Modul 'Project1.exe'. Schreiben von Adresse 7473654C' aufgetreten.
Zitat:
0000: 54 65 73 74 20 54 65 73 74 20 54 65 73 74 20 54 Test Test Test T
0010: 65 73 74 20 54 65 73 74 20 54 65 73 74 20 54 65 est Test Test Te
0020: 73 74 20 54 65 73 74 20 54 65 73 74 20 54 65 73 st Test Test Tes
0030: 74 0D 0A 54 65 73 74 20 54 65 73 74 20 54 65 73 t..Test Test Tes
0040: 74 20 54 65 73 74 20 54 65 73 74 20 54 65 73 74 t Test Test Test
0050: 20 54 65 73 74 20 54 65 73 74 20 54 65 73 74 20 Test Test Test
0060: 54 65 73 74 0D 0A 54 65 73 74 20 54 65 73 74 20 Test..Test Test
0070: 54 65 73 74 20 54 65 73 74 20 54 65 73 74 20 54 Test Test Test T
Kann mir jemand sagen, was ich falsch mache? Welchen Datentyp muss ich die Varable Data verwenden und wie muss ich diese mit Stream.Read() nutzen, damit die korrekten Daten ohne Fehler gelesen werden?

Besten Dank
Ares
  Mit Zitat antworten Zitat