Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Datei binär auslesen (Delhpi 7) (https://www.delphipraxis.net/189264-datei-binaer-auslesen-delhpi-7-a.html)

Captnemo 23. Mai 2016 15:56

Datei binär auslesen (Delhpi 7)
 
Hi,

ich versuche gerade eine DB-Datei binär auszulesen.
Mit dem Header hat das soweit auch gut geklappt. Nur mit den Daten habe ich ein Problem (was sicherlich zwischen meinen Ohren sitzt).

Hier mal ein bisschen Code:

Delphi-Quellcode:
  TDatenArray = array of Byte;

.
.
.
Procedure DatenAuslesen(fs: TFileStream);
var
  fieldcount: Integer;
  EndOfFields: Boolean;
  i, f, d: Integer;
  c: Integer;
  Feldname: string;
  daten: TDatenArray;
  fieldbytes: Integer;
  fieldoffset: Integer;
  fieldtext: string;
  newposition: Integer;
  bytesread: Integer;
begin


  //Hier passieren noch einige Dinge
  //Alle unten aufgeführten Vars werden initialisiert
  //Zur Demo setzt ich notwenige Daten direkt

  Datasize=1607;

  SetLength(daten, DataSize);
  //Setze Zeiger auf ersten Datensatz
  newposition:=fs.Seek(DataOffset, soFromBeginning);
  for i:=0 to 100 do begin //Alle Datensätze durch gehen (erstmal nur die ersten 100)
    bytesread:=fs.Read(daten, DataSize);
    fieldoffset:=0;
    if bytesread=DataSize then begin
      for f:=1 to 10 do begin //Alle Felder durchgehen (erstmal nur die ersten 10)
        fieldbytes:=StrToInt(sg_tabellenstructur.Cells[2, f]);
        fieldtext:='';
        case StrToInt(sg_tabellenstructur.Cells[5, f]) of
          67: begin
                for d:=0 to fieldbytes-1 do
                  fieldtext:=fieldtext+chr(daten[d+fieldoffset]); //Hier tritt ein Fehler Zugriffsverletzung auf. d ist dann 0 und fieldoffset ist 40.
              end;
        end;
        sg_Daten.Cells[f, i+1]:=fieldtext;
        fieldoffset:=fieldoffset+fieldbytes;
      end;
    end else Exit;
  end;
end;
Mir ist nicht klar, warum hier eine Zugriffsverletzung auftreten kann.

Ich habe den Code mal soweit eingekürzt, damit nichts unnötiges hier steht. Laut Bytesread müssten doch exakt soviel Bytes gelesen worden sein, dass das Daten-Array entsprechend gefüllt ist. Und wenn das Daten-Array nicht vorhanden wäre, dann müsste ja schon die read-operation fehlschlagen. Der Debugger zeigt mir nach der SetLength-Funktion auch das Array entsprechend an (Angezeigt wird: (0,0,0,0,0,....) ), aber nach read-Funktion sieht es im Debugger so aus, als hätte das Array eine länge von 0 (Angezeigt wird: () )

himitsu 23. Mai 2016 16:05

AW: Datei binär auslesen (Delhpi 7)
 
Ich bin mir fast sicher, dass Delphi 7 noch kein TStream.Read mit TBytes-Parameter kennt,
als
Delphi-Quellcode:
fs.Read(daten, DataSize);
=>
Delphi-Quellcode:
fs.Read(daten[0], DataSize);
, denn du willst ja den Array-Inhalt und nicht den Array-Zeiger überschreiben, da der Compiler bestimmt die Variante mit dem offenen VAR-Parameter verwendet. :stupid:

http://docwiki.embarcadero.com/Libra...s.TStream.Read
http://docwiki.embarcadero.com/VCL/2...s.TStream.Read

Captnemo 23. Mai 2016 16:19

AW: Datei binär auslesen (Delhpi 7)
 
Naja, beim Header klappt's ja ganz gut


Delphi-Quellcode:
TDBHeader = array[0..31] of Byte;
.
.
.
  TForm1 = class(TForm)
  .
  .
  private
    inputFS: TFileStream;
    DBHeader: TDBHeader;
  .
  .
  end;
.
.
.
.
procedure TForm1.GetHeader(fs: TFileStream);
begin
  fs.Read(DBHeader, SizeOf(DBHeader));
end;
Der einzige Unterschied den ich sehe ist, dass ihr hier ein statisches Array habe.

himitsu 23. Mai 2016 16:26

AW: Datei binär auslesen (Delhpi 7)
 
Der Header ist aber auch ein statisches Array und das ist wie ein Record.
Ein dynamisches Array ist aber ein Pointer, der dann auf den Arrayinhalt zeigt.
Und ohne Dereferenzierung schreibst du dann in den Pointer und nicht in die Daten.

Beim Statischen sind die Daten dagegen direkt in der Variable drin.

SizeOf(Daten) = 4
SizeOf(DBHeader) = mehr

Captnemo 23. Mai 2016 16:28

AW: Datei binär auslesen (Delhpi 7)
 
Ahhhh.....dann verstehe ich das.

Danke.

himitsu 23. Mai 2016 16:31

AW: Datei binär auslesen (Delhpi 7)
 
Darum am Besten immer Dereferenzieren, egal ob statisch oder dynamisch ... da kann dann nie was schief gehen.

Entweder
Delphi-Quellcode:
Datan[Low(Daten)]
oder du sagst "bei mir beginnt Statisches immer bei 0", dann
Delphi-Quellcode:
Datan[0]
.

p80286 23. Mai 2016 16:36

AW: Datei binär auslesen (Delhpi 7)
 
Wenn Du auch dynamische Arrays nutzt, dann gewöhn Dir z.B. fs.read(meinarray,anzahl); ganz schnell ab und mach es so
Delphi-Quellcode:
fs.read(Meinarray[low],anzahl);
Das geht soweit ich weiß bei statischen und Dynamischen Arrays und funktioniert dann immer.
(also immer wenn Du auf ein Array zugreifen willst, nur über den Index gehen)

Gruß
K-H

Edith:
seit wann
Delphi-Quellcode:
low(MeinArray)
? Ich kenn es nur ohne Angabe des Arrays.

Captnemo 23. Mai 2016 16:38

AW: Datei binär auslesen (Delhpi 7)
 
Ich brauch doch noch etwas Unterstützung bei der Umsetzung.

Wenn ich das so mache:

Delphi-Quellcode:
PDatenArray = Array of Byte;
TDAtenArray = ^PDatenArray;

procedure ....
var
  Daten = TDatenArray;
begin
  Datasize=1607;

  SetLength(Daten^,Datasize);
.
.
.
.
end;
Dann knallt es bei SetLength.

Captnemo 23. Mai 2016 16:39

AW: Datei binär auslesen (Delhpi 7)
 
Zitat:

Zitat von p80286 (Beitrag 1338747)
Wenn Du auch dynamische Arrays nutzt, dann gewöhn Dir z.B. fs.read(meinarray,anzahl); ganz schnell ab und mach es so
Delphi-Quellcode:
fs.read(Meinarray[low],anzahl);
Das geht soweit ich weiß bei statischen und Dynamischen Arrays und funktioniert dann immer.
(also immer wenn Du auf ein Array zugreifen willst, nur über den Index gehen)

Gruß
K-H

Das werde ich auch mal ausprobieren. Aber wenn ich das richtig verstanden habe kommt beides auf's gleiche raus.

p80286 23. Mai 2016 16:39

AW: Datei binär auslesen (Delhpi 7)
 
Delphi-Quellcode:
setlength(Daten,AnzahlElemente);
Gruß
K-H

Zitat:

Zitat von Captnemo (Beitrag 1338750)
Das werde ich auch mal ausprobieren. Aber wenn ich das richtig verstanden habe kommt beides auf's gleiche raus.

korrekt!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr.
Seite 1 von 2  1 2      

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