AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Daten aus einem Stream lesen und darstellen
Thema durchsuchen
Ansicht
Themen-Optionen

Daten aus einem Stream lesen und darstellen

Ein Thema von Ares · begonnen am 18. Feb 2008 · letzter Beitrag vom 18. Feb 2008
Antwort Antwort
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
Nuclear-Ping
(Gast)

n/a Beiträge
 
#2

Re: Daten aus einem Stream lesen und darstellen

  Alt 18. Feb 2008, 13:20
Warum übergibst du nicht den Pointer des Streams? (Hast da übrigens 'n Speicherleck )

Delphi-Quellcode:
unit main;

...

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

implementation

{$R *.dfm}

procedure TForm1.readBtClick(Sender: TObject);
var Stream: TFileStream;
begin
  Stream := TFileStream.Create('D:\Test.txt', fmOpenRead or fmShareDenyNone);
  try
    Stream.Seek(0, soFromBeginning);
    Stream.Read(Data[0], 128);
    Stream.Position := 0;
    Memo1.Lines.AddStrings(ShowBinary(Stream.Memory, Stream.Size));
  finally
    FreeAndNil (Stream);
  end;
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: Pointer; 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;
  Mit Zitat antworten Zitat
jottkaerr

Registriert seit: 2. Jul 2007
Ort: Tuttlingen
81 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

Re: Daten aus einem Stream lesen und darstellen

  Alt 18. Feb 2008, 13:23
Hallo,

Dein Aufruf von ShowBinary() ist falsch. Auch dort musst Du Data[0] als ersten Parameter übergeben. Das erklärt auch, wieso die zweite, eigentlich falsche Variante des Aufrufs von Stream.Read() zuerst zu funktionieren scheint: Du überschreibst hier den Bereich, an dem Deine lokalen Variablen (und die Rücksprungadresse) liegen, und liest diesen Bereich in ShowBinary() wieder aus. Beim Verlassen von readBtClick() scheppert's dann.

jkr
Jürgen Krämer
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)
  Mit Zitat antworten Zitat
Ares

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

Re: Daten aus einem Stream lesen und darstellen

  Alt 18. Feb 2008, 13:33
Zitat von jottkaerr:
Hallo,

Dein Aufruf von ShowBinary() ist falsch. Auch dort musst Du Data[0] als ersten Parameter übergeben.
Vielen Dank für den Hinweis! Jetzt funktioniert es prima!
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#5

Re: Daten aus einem Stream lesen und darstellen

  Alt 18. Feb 2008, 19:01
@Nuclear-Ping: Dein Code klappt so auch nicht, da du eine Property nicht als Var Parameter angeben kannst.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz