AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Datei mit FileStream auslesen

Ein Thema von delphinewbie · begonnen am 27. Aug 2010 · letzter Beitrag vom 10. Sep 2010
Antwort Antwort
delphinewbie

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

Datei mit FileStream auslesen

  Alt 27. Aug 2010, 08:36
Delphi-Version: 2005
Guten Morgen Delphi-Gemeinde,
ich habe mich hier gerade angemeldet und das nicht ohne Grund. Ich bin gerade dabei, mich ein wenig ins Delphi einzuarbeiten und auf der Suche nach geballtem Wissen bin ich nun hier gelandet. Ich habe den Eindruck, dass mir hier geholfen werden kann. Also wie gesagt, ich bin ein absoluter Einsteiger und ich hoffe, dass ihr mir meine vllt. primitiven Fehler verzeiht. Doch nun zu meinem Problem :
Ich möchte eine typisierte (oder heißt das strukturierte ) Datei (Byte für Byte) auslesen und die darin enthaltenen Daten natürlich weiterbearbeiten. Mir ist auch bekannt, wie diese Datei aufgebaut ist, d.h. wo steht ein String, wie lang ist er, wo steht ein integer u.s.w. und ich erhalte auch sinnvolle Daten, wie sie zu erwarten wären. Leider erhalte ich dann jedoch beim Beenden des Programms (in der IDE) eine Fehlermeldung.

Im Projekt xxx.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung : 'Zugriffsverletzung bei Adresse 0040438A in Modul 'xxx.exe'. Lesen von Adresse 00000018'.
Prozess wurde angehalten. Mit einzelne Anweisung oder Start fortsetzen.

Starte ich die xxx.exe bspw. aus dem Windows-Explorer, kommt nach Programmbeendigung die Meldung :
xxx.exe funktioniert nicht mehr
Windows kann online nach einer Lösung für das Problem suchen.
u.s.w blabla....


Quellcode (Ausschnitt) :

type

bytes = record

// Global section
FileID : word;
data_offset : Longint;
L_of_Filecomment : word;
Filecomment : string;
Length_of_Reserve_string : array[1..32] of byte;
Reserve_string : array[1..32] of string;
end;

var
Form1: TForm1;
f : TFileStream;
ds: bytes;

implementation
.
.
.

if OpenDialog1.Execute then
begin
f:=(TFileStream.Create(OpenDialog1.FileName,fmOpen Read));
pfad:= OpenDialog1.FileName;

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));
Read(ds.Reserve_string[i],ds.Length_of_Reserve_string[i]);
end;

Read(ds.NofChan,sizeof(word));
Read(ds.max_chan_length,sizeof(longint));
.
.
.
.
end; // end with f do
f.Free;
end; // if OpenDialog1.Execute
.
.

Das Eigenartige an der Sache ist jedoch, dass diese Fehler nicht auftreten, wenn alles ab der for-Schleife auskommentiert wird. Beginnt die Auskommentierung nur 3 Zeilen weiter, also bei Read(ds.NofChan,sizeof(word));, habe ich schon die Fehlermeldung!!! Hängt es irgendwie mit der for-Schleife zusammen oder mache ich bei den String-Arrays Fehler ?
Hat jemand eine Idee zu diesem sicherlich einfachen Problem ?
Vielen Dank,
delphinewbie
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.655 Beiträge
 
Delphi 12 Athens
 
#2

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 10:37
Hallo und Willkommen in der DP ,

ich denke, das Hauptproblem sind die Strings. Ein String ist in Delphi(2 - 2007) ein AnsiString, in neueren Versionen ein Unicode-String. AnsiStrings sind intern nur erst einmal ein Zeiger, also 4 Byte groß. Speicherst Du diesen und lädst ihn wieder, ist dieser Zeiger ungültig bzw. zeigt ganz woanders hin. Um das zu umgehen, solltest Du ShortStrings verwenden, diese sind allerdings auf 256 Zeichen begrenzt. Brauchst Du mehr, musst Du wohl auf statische Char-Arrays ausweichen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
900 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 11:07
Das Problem dürfte sein, dass du die Länge der Strings vorher nicht pasend setzt. So sollte das gehen:
Delphi-Quellcode:
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;
Also: Erst die Länge des Strings aus der Datei lesen, diese Länge auf den String übertragen, und dann die Daten in den String laden, Startposition ist dann das erste Zeichen in dem String.
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
delphinewbie

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

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 11:14
Hi DeddyH,
ne, hat nicht geholfen. Der Zeiger wird doch aber nicht verändert, wenn ich die Datei nur hintereinander auslese, oder ? Und wie gesagt, die Datei wird ja auch richtig ausgelesen.
Die Fehlermeldung kommt erst beim Beenden des Programms , also der xxx.exe.
Es sieht ja fast so aus, als ob dann beim Programmbeenden eine unzulässige Adresse angesprochen wird. Aber wieso ?
Gibt es eigentlich noch andere Möglichkeiten außer mit TFileStream, derartige Dateien auszulesen ? Den Dateien kann man auch keine konstante Struktur zuordnen, sodass man mit records hätte arbeiten können.
Das Problem dabei ist ja, dass die Dateilänge nie gleich ist, abhängig davon z.B. wie lang Kommentare sind oder wieviele Datenkanäle abgespeichert wurden. Diese Angaben finde ich immer erst direkt in der Datei, aber das funktioniert ja auch richtig. Nur eben das Ende...

Vielen Dank
  Mit Zitat antworten Zitat
delphinewbie

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

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 11:20
@Gausi,
danke, aber ich bekomme die gleiche Fehlermeldung, nur sind die Adressen, bei denen die Zugriffsverletzung auftritt anders.

Ich bin ratlos
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.655 Beiträge
 
Delphi 12 Athens
 
#6

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 11:25
Zitat:
Delphi-Quellcode:
Length_of_Reserve_string : array[1..32] of byte;
...
Read(ds.Length_of_Reserve_string[i],sizeof(word));
Das Array ist 32 Byte groß, Du liest aber 64 Byte (Word = 16 Bit). Außerdem müsstest Du (wenn ich das richtig sehe) wohl erst das Byte-Array komplett befüllen und erst anschließend das String-Array.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
delphinewbie

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

AW: Datei mit FileStream auslesen

  Alt 27. Aug 2010, 11:54
ok, habe das array jetzt auf word gesetzt.

Length_of_Reserve_string : array[1..32] of word;
Reserve_string : array[1..32] of string;

Ich kann aber nicht erst das eine array füllen und dann das andere, weil die Reichenfolge beim Lesen eben so ist :
1. Lesen von 2 bytes (Länge L des nachfolgenden strings
2. Lesen von L*bytes ( der string selbst)
Oder habe ich dich falsch verstanden ?

Fehlermeldung bleibt leider immer die gleiche
  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 17:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz