Registriert seit: 27. Aug 2010
47 Beiträge
|
AW: Datei mit FileStream auslesen
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
Geändert von delphinewbie (31. Aug 2010 um 10:32 Uhr)
|