AGB  ·  Datenschutz  ·  Impressum  







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

Problem beim Datei auslesen in ein Array

Ein Thema von Quick_silver · begonnen am 21. Sep 2006 · letzter Beitrag vom 21. Sep 2006
Antwort Antwort
Seite 1 von 2  1 2      
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#1

Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 17:47
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:
    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;
DIe Daten will ich in dieses Array:
Delphi-Quellcode:
type
  TDatensatz = record
    ID: integer;
    Text: AnsiString;
  end;

  TDatenArray = array of TDatensatz;
Und das ist mein versuch der imemr irgnedwleche Speicherzugriffsfehler auswirft und das Programm crasht:

Delphi-Quellcode:
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;
Wie kann ich das ganze eleganter lösen?
  Mit Zitat antworten Zitat
panzerfischer

Registriert seit: 18. Sep 2006
Ort: Ilmenau
33 Beiträge
 
#2

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 17:52
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
  Mit Zitat antworten Zitat
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#3

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 17:57
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.
  Mit Zitat antworten Zitat
panzerfischer

Registriert seit: 18. Sep 2006
Ort: Ilmenau
33 Beiträge
 
#4

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:03
also die typdeklaration ist schon mal gut, ansonsten, warum ließt du nicht die datei im ganzen aus?

z.b. so:
Delphi-Quellcode:
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);
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
außerdem musst du die länge des strings festlegen, weil der rechner ja sonst nicht weiß, wie lang die datei nun ist
  Mit Zitat antworten Zitat
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:09
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.
  Mit Zitat antworten Zitat
panzerfischer

Registriert seit: 18. Sep 2006
Ort: Ilmenau
33 Beiträge
 
#6

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:30
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?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:35
Zitat von panzerfischer:
also die typdeklaration ist schon mal gut, ansonsten, warum ließt du nicht die datei im ganzen aus?

z.b. so:
Delphi-Quellcode:
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);
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
außerdem musst du die länge des strings festlegen, weil der rechner ja sonst nicht weiß, wie lang die datei nun ist
Das geht nicht weil in TDatensatz ein Ansistring enthalten ist was widerum nur ein Pointer ist.

@Quick_silver: Wenn Len bei dir ein Integer (4 Byte) ist und du mit
fs.Read(Len, 2); 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".
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.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#8

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:39
Hi,
kannst du dann vielleicht eine solche Datei posten?

Ansonsten sehe ich nicht ganz warum dein Code nur so arbeiten sollte.
Delphi-Quellcode:
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;
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).

Gruß Der Unwissende

[edit]
Delphi Tag geöffnet, quote geschlossen...
[/edit]
  Mit Zitat antworten Zitat
panzerfischer

Registriert seit: 18. Sep 2006
Ort: Ilmenau
33 Beiträge
 
#9

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:42
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
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 18:45
Zitat von panzerfischer:
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
Ansistring sagt aus das es String mit variabler Länge ist und somit nur ein Pointer. Bei einem Ansistring liegen die eigentlichen Daten also irgendwo und nicht hinter der Adresse der Variablen.
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)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 18:32 Uhr.
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