![]() |
Problem beim Datei auslesen in ein Array
Ich will eine Datei auslesen.
Dafür habe folgenden Code: Inhalt der Datei: 02 00 00 00 01 00 <ID 21 A1 07 00> <Stringlänge 00 13> 00 <string> <ID> <Stringlänge> 00 <string> <ID> <Stringlänge> 00 <string> etc...
Delphi-Quellcode:
DIe Daten will ich in dieses Array:
fs.Seek(6,0); //Die ersten Bytes überspringen
fs.Read(id, 4); fs.Seek(1, 1); //Ein byte überspringen (gibt es ne bessere lösung?) fs.Read(Len, 2); SetLength(text, Len); fs.Read(PChar(text)^, Len); //daten[i].id := id; //daten[i].text := text;
Delphi-Quellcode:
Und das ist mein versuch der imemr irgnedwleche Speicherzugriffsfehler auswirft und das Programm crasht:
type
TDatensatz = record ID: integer; Text: AnsiString; end; TDatenArray = array of TDatensatz;
Delphi-Quellcode:
Wie kann ich das ganze eleganter lösen?
procedure TForm1.ReadData(datei : string; var daten : TDatenArray );
var fs : TStream; i, id, Len : Integer; text : string; begin fs := TFileStream.Create(datei, fmOpenReadWrite); fs.Seek(6,0); i := 0; while fs.Position < fs.Size do begin inc(i); SetLength( daten, i ); fs.Read(id, 4); fs.Seek(1, 1); //Will ich weg haben fs.Read(Len, 2); //Wieso nur 2 bytes? SetLength(text, Len); fs.Read(PChar(text)^, Len); daten[i].id := id; daten[i].text := text; //Immerhin funktionniert die schleife überhaupt erst mit der folgenden Zeile. *schulterzuck* //Ohne diel iest er nur den ersten eintrag. ListBox.Items.Add( IntToStr(fs.Position) +'<'+IntToStr(fs.Size) ); end; fs.Free; end; |
Re: Problem beim Datei auslesen in ein Array
was soll denn in der datei stehen (bitte nicht in einsen und nullen(auch kein hexcode)) man muss es ja nicht schlimmer machen als es ist
|
Re: Problem beim Datei auslesen in ein Array
Eine ID (Integer) und ein String der zu dieser ID gehört.
Davon einige tausend. Könnte man aus dem gepostet Code auch erahnen :/ Das auslesen funktioniert ja auch grob so. Also die Variablen ID und Text werden schon richtig gefüllt. |
Re: Problem beim Datei auslesen in ein Array
also die typdeklaration ist schon mal gut, ansonsten, warum ließt du nicht die datei im ganzen aus?
z.b. so:
Delphi-Quellcode:
speichern funktioniert ähnlich. hat halt den nachteil, dass du die größe vom array festlegen musst, weil du vorher nicht weißt wieviel drinne steht
type TDatensatz = record ID: integer; Text: AnsiString; end;
var TDatenArray = array[0..viel] of TDatensatz; TDatenfile = file of datensatz; .. assignfile(TDatenfile,'pfad/datei'); {$I-} //eingabe/ausgabe fehler werden ignoriert reset(TDatenfile); {$I+} if IoResult = 0 then begin i:=0; while not eof do {end of file} read(TDatenfile,TDatenarray[i]); inc(i); end; closefile(TDatenfile); außerdem musst du die länge des strings festlegen, weil der rechner ja sonst nicht weiß, wie lang die datei nun ist |
Re: Problem beim Datei auslesen in ein Array
Also
var TDatenArray = array[0..viel] of TDatensatz; kann ich schlecht nehmen, ich muss schon vorher rausfinden wie viele DAtensätze ich habe, oder das array dynamisch während des auslesens erweitern. Zudem wird dein Vorschlag wohl 6 bytes zu fürh anfangen zu lesen, oder nicht? Die Länge der Text Variable muss ebenfalls vor jedem Eintrag neu fest gelegt werden. Da die Strings ja nicht immer gleich lang sein. Eigentlich so gut wie nie. |
Re: Problem beim Datei auslesen in ein Array
eigendlich nicht, da die 6byte zum kopf gehören, und nicht ausgelesen werden, bei der größe der strings musst du wissen, mit welcher größe die gespeichert wurden, damit es nicht zu verschiebungen kommt, kann aber auch sein, das der computer erkennt, wie groß der string ist, da nomalerweise vor dem ersten buchstaben die länge steht, musst du mal ausprobieren
ein dynamisches array erweitern könnte gut funktionieren woher kommt die datei, bzw. womit hast du sie erstellt? |
Re: Problem beim Datei auslesen in ein Array
Zitat:
@Quick_silver: Wenn Len bei dir ein Integer (4 Byte) ist und du mit
Delphi-Quellcode:
nur 2 Byte in diese Variable einliest sind die anderen 2 Byte weiterhin undefiniert. Das heißt in den restlichen 2 Byte steht weiter irgendwelcher Zufallsmüll. Entweder nimmst du als Typ "word" oder initialisierst die Variable vorher mit "0".
fs.Read(Len, 2);
Am besten du debugst das ganze mal und prüfst nach jedem schritt welche Werte die Variablen haben. Dann weißt du auch wo du daneben greifst. |
Re: Problem beim Datei auslesen in ein Array
Hi,
kannst du dann vielleicht eine solche Datei posten? Ansonsten sehe ich nicht ganz warum dein Code nur so arbeiten sollte.
Delphi-Quellcode:
So sollte das ganze eigentlich klappen (wenn die Datei so aufgebaut ist wie du sagst (und natürlich ich keinen Fehler gemacht habe). An sich empfiehlt sich hier eine Liste. Intern wird zwar auch ein Array verwendet und du kannst auch per Index wahlfrei auf bestimmte Elemente zugreifen, aber die Größenanpassung ist hier von Delphi übernommen. Dein Array immer nur um 1 Element zu erweitern ist sehr schlecht. Es kostet Zeit neuen Speicher zu allozieren und das alte Array dort reinzukopieren. Eine List alloziert gleich eine vielzahl von weiteren Elementen. Sind diese neu allozierten Plätze zu einem gewissen Grad gefüllt, wird wieder um ein gutes Stück vergrößert. Hast du einen Overhead (an Zeit) von O, dann teilt der sich damti auf die Anzahl n der allozierten Elemente auf, ist also in deinem Fall 0/1 = O und das in jeder Iteration, im Falle der Liste O/n und n ist halt von Delphi gewählt (und das passiert automatisch).
var List : TList;
fs : TFileStream; buffer : ^TDatensatz; length : Integer; begin list := Tlist.Create; ... try while (fs.Position < fs.Size) do begin new(buffer); fs.Read(buffer.id, 4); fs.Position := fs.Position + 1; fs.Read(length, 2); fs.Position := fs.Position + 1; setLength(buffer.Text, length); fs.Read(buffer.Text, length); list.Add(buffer); end; finally fs.Free; end; end; Gruß Der Unwissende [edit] Delphi Tag geöffnet, quote geschlossen... [/edit] |
Re: Problem beim Datei auslesen in ein Array
ansistring sagt doch nur aus, das max. 2^31buchstaben gespeichert werden können. vor jedem string steht die länge des strings also die ersten 4byte in diesem fall, die auskunft über die länge geben.
könnte sogar so sein, das es sich bei dmn integer wert in seiner datei, um die länge des strings handelt, ich weiß ja nicht genau, was das für ne file ist |
Re: Problem beim Datei auslesen in ein Array
Zitat:
Du kannst ja mal SizeOf(DeineAnsiStringVariable) ausgeben lassen. Du wirst immer 4 zurück bekommen weil der AnsiString eben nur 4 Byte groß ist (bei einem 32bit compiler) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:44 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-2025 by Thomas Breitkreuz