Einzelnen Beitrag anzeigen

delphinewbie

Registriert seit: 27. Aug 2010
47 Beiträge
 
#24

AW: Datei mit FileStream auslesen

  Alt 31. Aug 2010, 10:04
Guten Morgen,
tja , das zu lesende File hat eine ziemlich komplizierte Struktur. Es handelt sich hierbei um Dateien, die mittels eines Messverstärkers erstellt wurden.
Ich hänge mal die Beschreibung als PDF-Dokument an sowie eine Messwertdatei als Beispiel (3 Messkanäle mit je 36000 Werten).
Zusätzlich füge ich mal meine Struktur als Delphi-Code hinzu:
Delphi-Quellcode:
messwertdatei = record

// Global section
  FileID : word;
  data_offset : Longint;
  L_of_Filecomment : word;
  Filecomment : string;
  Length_of_Reserve_string : array[1..32] of word;
  Reserve_string : array[1..32] of string;
  NofChan : word;
  max_chan_length : Longint;
  offset_chan_length_entry : array[1..255] of longint;
  reduction_factor : Longint;

//Channel header section
  ch_location_in_database : array[1..255] of word;
  NVals : array[1..255] of longint; //Anzahl der Meßwerte im jeweiligen Kanal
  str_length_ch_name : array[1..255] of word; //Länge Kanalname in Bytes
  ch_name : array[1..255] of string; //Kanalbezeichnung
  string_length_unit : array[1..255] of word;
  string_unit : array[1..255] of string; //Einheitenbezeichnung pro Kanal
  string_length_date : array[1..255] of word;
  string_date : array[1..255] of string; //Datum der Messung
  string_length_time : array[1..255] of word;
  string_time : array[1..255] of string; //Uhrzeit der Messung
  string_length_comment : array[1..255] of word;
  string_comment : array[1..255] of string; //Kommentar
  format : array[1..255] of word; //Datenformat : 0-numerisch, 1-string, 2-binär
  data_width : array[1..255] of word; //Datenbreite: numerisch-immer 8 Byte, string- >=8 Byte
  date_time : array[1..255] of double; //Datum,Zeit der Messung, neues Format
  size_ext_ch_header : array[1..255] of longint; //Größe des extended channel-header
  ext_ch_header : array[1..255] of string; //extended Channelheader muss noch
                                                // untersetzt werden, falls nötig
  lin_mode : array[1..255] of byte; //Linearisierungsmode
  user_scale_type :array[1..255] of byte;
  number_of_points_nScaleData : array[1..255] of byte;
  nScaleData : array[1..255] of double; //abhängig vom Skalierungstyp
  thermo_typ :array[1..255] of word;
  length_formula : array[1..255] of word;
  formula : array[1..255] of string; // Formel, wenn length_formula > 0
  size_sensor_info : array[1..255] of longint;
  sensor_info : array[1..255] of string; //sensor_info muss noch
                                                // untersetzt werden, falls Daten speziell benötigt werden
  end;
.. und nun wie ich die Datei auslese :
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,s,z : integer;
b : byte;
export_format : integer;


begin
freearray;
zmax:=1; smax:=1;
dimArray(1,1);
with OpenDialog1 do
      begin
        DefaultExt := '.bin';
        Filter := 'Catman-Datei (*.bin)|*.bin';
        Title := 'Catman-datei oeffnen';
      end;
if OpenDialog1.Execute then
 begin
  f:=(TFileStream.Create(OpenDialog1.FileName,fmOpenRead));
  pfad:= OpenDialog1.FileName;
  Form2.Caption := pfad; // Anzeige Dateipfad in Titelleiste des Formulars 2
  with f do begin
  Read(ds.FileID,sizeof(word));
  Read(ds.data_offset,sizeof(longint));
  Read(ds.L_of_Filecomment,sizeof(word));
  if ds.L_of_Filecomment <> 0 then
      Read(ds.Filecomment[1],ds.L_of_Filecomment);
  for i:=1 to 32 do begin
  Read(ds.Length_of_Reserve_string[i],sizeof(word));
  SetLength(ds.Reserve_string[i], ds.Length_of_Reserve_string[i]);
  Read(ds.Reserve_string[i][1], ds.Length_of_Reserve_string[i]);
  end;
  Read(ds.NofChan,sizeof(word));
  Read(ds.max_chan_length,sizeof(longint));
  for i:=1 to ds.NofChan do begin
      Read(ds.offset_chan_length_entry[i],sizeof(longint));
  end;
  Read(ds.reduction_factor,sizeof(longint));

 // Auslesen Channel-Header
  for i:=1 to ds.NofChan do begin
      Read(ds.ch_location_in_database[i],sizeof(word));
      Read(ds.NVals[i],sizeof(longint));

      Read(ds.str_length_ch_name[i],sizeof(word));
      SetLength(ds.ch_name[i], ds.str_length_ch_name[i]);
      Read(ds.ch_name[i][1],ds.str_length_ch_name[i]);


      Read(ds.string_length_unit[i],sizeof(word));
      SetLength(ds.string_unit[i], ds.string_length_unit[i]);
      Read(ds.string_unit[i][1],ds.string_length_unit[i]);


      if ds.FileID < 5009 then begin
      Read(ds.string_length_date[i],sizeof(word));
      SetLength(ds.string_date[i], ds.string_length_date[i]);
      Read(ds.string_date[i][1],ds.string_length_date[i]);

      Read(ds.string_length_time[i],sizeof(word));
      SetLength(ds.string_time[i], ds.string_length_time[i]);
      Read(ds.string_time[i][1],ds.string_length_time[i]);
      end;

      Read(ds.string_length_comment[i],sizeof(word));
      Setlength(ds.string_comment[i], ds.string_length_comment[i]);
      Read(ds.string_comment[i][1],ds.string_length_comment[i]);

      Read(ds.format[i],sizeof(word));
      Read(ds.data_width[i],sizeof(word));
      Read(ds.date_time[i],sizeof(double));
      Read(ds.size_ext_ch_header[i],sizeof(longint));
      Read(ds.ext_ch_header[i],ds.size_ext_ch_header[i]);
      Read(ds.lin_mode[i],sizeof(byte));
      Read(ds.user_scale_type[i],sizeof(byte));
      Read(ds.number_of_points_nScaleData[i],sizeof(byte));
      Read(ds.nScaleData[i],ds.number_of_points_nScaleData[i]*sizeof(double));
      Read(ds.thermo_typ[i],sizeof(word));
      Read(ds.length_formula[i],sizeof(word));
      if ds.length_formula[i]>0 then begin
        Setlength(ds.formula[i], ds.length_formula[i]);
        Read(ds.formula[i][1],ds.length_formula[i]);

      end;
      Read(ds.size_sensor_info[i],sizeof(longint));
      Setlength(ds.sensor_info[i], ds.size_sensor_info[i]);
      Read(ds.sensor_info[i][1],ds.size_sensor_info[i]);

  end; //end for i:=1 to ds.NofChan

// Auslesen Data area

export_format := 0; //zum TEST :export_format wird 0 gesetzt, weil Messwerte hier als double abgespeichert sind und export_format noch nicht ausgewertet wird
if export_format = 0 then begin
    zmax:= ds.NofChan;
    smax:= ds.NVals[1];
    freearray;
    dimArray(zmax,smax);
    for s:=1 to ds.NofChan do
    for z:=1 to ds.NVals[1] do begin
        Read(wert,sizeof(double));
         wrA(s,z,wert);
      end;
   end; //end if export_format = 0

 end; // end with f do
  f.Free;
end; // if OpenDialog1.Execute

//Anzeige Messwerttabelle
form2.Show;

end;
... zur Vollständigkeit noch die anderen verwendeten Routinen...
Delphi-Quellcode:
type dArray = array[1..1] of Variant;

var
dA: ^dArray;

 procedure dimArray; (* dyn. Speicher reservieren *)
 begin
  smax := s; zmax := z;
  GetMem(dA, SizeOf(dA^[1])* zmax * smax)
 end;

 procedure freeArray; (* dyn. Speicher wieder freigeben *)
 begin
  FreeMem(dA,SizeOf(dA^[1])* zmax * smax)
 end;

 procedure wrA; (* Schreibzugriff *)
 begin
  dA^[(z-1)* smax + s] := w
 end;
So, ich denke, ich habe alles wichtige nun gezeigt. Wenn ihr eine Lösungsidee habt, wäre ich euch unendlich dankbar. Die Fehlermeldung nach Programmende kann ja auf Dauer nicht sein !

P.S.: Oder kann es mit der Konfiguration Delphi7 und Vista zusammenhängen ?
Die Delphi-Hilfe läßt sich ja leider auch nicht installieren
Vielen Dank
Angehängte Dateien
Dateityp: pdf catmanbinaryformat.pdf (794,4 KB, 10x aufgerufen)
Dateityp: rar Messwerte.rar (261,9 KB, 4x aufgerufen)

Geändert von delphinewbie (31. Aug 2010 um 10:32 Uhr)
  Mit Zitat antworten Zitat