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 2 von 2     12   
panzerfischer

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 19:03
laut delphi hilfe ist der string max 2^31 zeichen lang (die länge als zahlenwert ist somit 4byte, aber nicht der string selbst)

mal abgesehen, geht es in diesem fall um die datei arbeit, nicht um speicherverwaltung, und in so ner datei, steht alles hintereinander, damit der rechner weit, welcher string wie lang ist, schreibt er die läge vorneweg.

es gab auch solche eol zeiger (end of line) aber ich glaube die haben sich auf textdateien bezogen, also dateien voller char's

ich meine 2^31 zeichen, das sind schon einpaar zeilen, glaube nicht, das seine strings so groß sind, im allgemeinen fall würde denke ich mal auch ein shortstring reichen, das sind auch schon 255 zeichen
  Mit Zitat antworten Zitat
Quick_silver

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 19:30
Hat nix mit dme Ansistring zu tun. Ich habe das Problem soweit gelößt.
Ich kann jetzt die ganze Datei auslesen:

Delphi-Quellcode:
procedure TForm1.ReadData(datei : string; var daten : TDatenArray );
var
fs : TStream;
i, id, check : Integer;
Len : Short;
text : string;
begin

  fs := TFileStream.Create(datei, fmOpenReadWrite);
  ProgressBar.Max := fs.Size;
  ProgressBar.Position := 0;

  fs.Seek(6,soFromBeginning);
  i := 0;

  repeat
    inc(i);
    SetLength( daten, i ); // datenarray lenge anpassen

    check := fs.Read(id, SizeOf(id)); //Id auslesen
    if check < SizeOf(id) then //Wenn es keine mehr gab abbrechen
      break;

    fs.Seek(1, soFromCurrent); //1 byte überspringen
    fs.Read(Len, SizeOf(Len)); //Lenge des Strings
    SetLength(text, Len); //Stringlänge setzten
    fs.Read(PChar(text)^, Len); //String auslesen

    daten[i-1].id := id;
    daten[i-1].text := text;
    //Label1.Caption := IntToStr(i);
    //Label1.Update;
    ProgressBar.StepBy(7+Len);

  until check < SizeOf(id);

  fs.Free;
end;
Für Len habe ich nen Short genommen, welcher nun nurnoch ähm 2Bye? Groß ist. Passt auf jedenfall.
Das unterbrechen habe ich auch ganz gut hinbekommen. Position und Size soll angeblich stark die Performence reduzieren.

Wobei wir auch genau beim nächsten Problem sind.
Meine Datei hat (die kleienre Variante) 18.000 Einträge.

Frage 1. Wieso liest er am anfang shcneller aus als zum Ende hin?
Frage 2. Was gibt es für eine Alternative zu meinem Array die daten schneller / besser zu speichern?
Und sonst, wo kann man noch Optimieren? Es dauert im moment echt arg lange
  Mit Zitat antworten Zitat
panzerfischer

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 19:34
von was wurde denn die datei/en erstellt? und in welchem format, das würde die sache enorm vereinfachen,
  Mit Zitat antworten Zitat
Quick_silver

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 19:55
Von was weiss ich nicht, also von den EA entwicklern wahrscheinlich.
Das ist ne Sprachdatei in der Strings gespeichert sind.
Der Client bekommt ne Nummer und gibt nen String aus. Was den Traffic verringert.
Geht um Ultima Online.

Spielt aber keine Rolle. Das format ist so wie ichs beschrieben habe. Mehr weiss ich nicht.
  Mit Zitat antworten Zitat
panzerfischer

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 20:15
wie oft willst du auf diese datei zugreifen, bzw, was hast du damit vor, willst bestimmte sachen ändern, und die wieder in das selbe format schreiben oder wie oder was?
  Mit Zitat antworten Zitat
Quick_silver

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 20:17
Kann es sein das die Daten über das Array sehr sehr platzverschwenderisch im Arbeitsspeicher verteilt werden? Anders kann ich mir das nicht vorstellen.
Aber wleche bessere Möglichkeit zur Verwlaung gibt es? Die Daten sleber sind nur 600KB bis 1,6MB groß... Das kann doch nicht so irrsinnig viel Speicher fressen.



Ich will:

Also ich habe 2 dieser Dateien. Ich will im endeffekt die eine in die andere Mergen.
Aus den 2 Dateien will ich eine erstellen in der Alle Strings aus beiden Dateien stehen. Falls in Datei1 einer vorhanden ist der in Datei2 auch vorhanden ist soll dieser überschrieben werden.

D.h. ich muss die ausgelesenn Datensätze auch sortieren können. Wofür sie dann ja wohl am besten im Arbeitsspeicher stehen sollten.
  Mit Zitat antworten Zitat
panzerfischer

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 20:24
nimm vieleicht mal was anderes als ansistring, das ist nunmal ein speicherfrsser
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#18

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 20:35
Delphi-Quellcode:
inc(i);
SetLength( daten, i );
Uuuh, schwerer Speicher- und Performancefresser. Kann es sein, dass die Anzahl der Items in den ersten sechs Byte der Datei steckt? Wenn ja, setze das Array einmalig auf diese Größe, ansonsten: Delphi-Referenz durchsuchenTList.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Quick_silver

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

Re: Problem beim Datei auslesen in ein Array

  Alt 21. Sep 2006, 21:22
Array imemr um 1000 statt 1 erhöhen reicht schon.
Aber die TList ist noch besser.
Hat aber eher den Grund das ich damit die Daten dann auch sortieren kann. Die Geschiwindigkeit ist nun angemessen.

Über das Soriteren (wovon ich noch keine Ahnung hab) recherchier ich erstmal im foum. Muss hier ja nicht auch noch breit getreten werden^^

Edit:
Und danke an alle die Geholfen haben.

Hier der Code, vll hilft es ja nochmal:
Delphi-Quellcode:
type
  TDatensatz = record
    ID: integer;
    Text: AnsiString;
  end;

  TDatenPointer = ^TDatensatz;


procedure TForm1.btnReadClick(Sender: TObject);
var
daten1, daten2 : TList;
i : Integer;
p : TDatenPointer;
begin

  daten1 := Tlist.create;
  daten2 := Tlist.create;

  Label1.Caption := 'Lese Datei: '+PathFrom.Text;
  Label1.Update;
  ReadData(PathFrom.Text, daten1);
  Label1.Caption := 'Lese Datei: '+PathTo.Text;
  Label1.Update;
  ReadData(PathTo.Text, daten2);
  //Merge - Muss nurnoch sortiert werden
  Label1.Caption := 'Merge...';
  Label1.Update;
  MergeData( daten1, daten2 );
  //Save - Fehlt noch


  for i := 0 to daten1.count-1 do
  begin
    p := TDatenPointer( daten1.items[ i ] );
    dispose( p );
  end;

  for i := 0 to daten2.count-1 do
  begin
    p := TDatenPointer( daten2.items[ i ] );
    dispose( p );
  end;

  Daten1.Free;
  Daten2.Free;

end;

procedure TForm1.ReadData(datei : string; var daten : TList );
var
fs : TStream;
p : TDatenPointer;

i,j, id, check : Integer;
Len : Short;
text : string;
begin
  fs := TFileStream.Create(datei, fmOpenReadWrite);
  ProgressBar.Max := fs.Size;
  ProgressBar.Position := 0;

  fs.Seek(6,soFromBeginning);
  i := 0;
  j := 1000;

  repeat
    inc(i);

    //Array verlängern
    //if Length( daten ) <= i then
      //SetLength( daten, Length( daten )+3000);


    check := fs.Read(id, SizeOf(id)); //Id auslesen
    if check < SizeOf(id) then //Wenn keinem ehr gab abbrechen
      break;

    fs.Seek(1, soFromCurrent); //1 byte überspringen
    fs.Read(Len, SizeOf(Len)); //Lenge des Strings
    SetLength(text, Len); //Stringlänge setzten
    fs.Read(PChar(text)^, Len); //String auslesen

    //daten[i-1].id := id;
    //daten[i-1].text := text;

    new( p );
    p.ID := id;
    p.Text:= text;
    daten.add( p );

    //Label1.Caption := IntToStr(i);
    //Label1.Update;
    ProgressBar.StepBy(7+Len);

  until check < SizeOf(id);

  fs.Free;
end;


//Veorläufige Verison, kann sicher noch stark optimiert werden:
procedure TForm1.MergeData( Daten1: TList; Daten2: TList);
var
IDsToAdd : array of integer;
i,j:integer;
found : Boolean;
p, p1, p2 : TDatenPointer;
begin
  ProgressBar.Position := 0;
  ProgressBar.Max := Daten2.Count;

  ListBox.Items.Add('Vor Merge Data1.Count: '+ inttostr(daten1.count));
  ListBox.Items.Add('Vor Merge Data2.Count: '+ inttostr(daten2.count));

  for i := 0 to Daten2.Count-1 do
  begin //Data 2 durchgehen
    p2 := TDatenPointer( daten2.items[ i ] );
    ProgressBar.StepBy(1);

    //Suchen ob data2 in data1 vorhanden ist
    found := false;
    for j:=0 to Daten1.Count-1 do
    begin
      p1 := TDatenPointer( daten1.items[ j ] );
      if p1.ID = p2.ID then
      begin
        found := true;
        break;
      end;
    end;

    if found <> true then //Die ID ist in Data1 NICHT vorhanden
    begin
      //Dann muss sie in Data 1 eingefügt werden...
      new( p );
      p.ID := p2.ID;
      p.Text:= p2.Text;
      daten1.add( p );
    end;
  end;

    ListBox.Items.Add('Nach Merge Data1.Count: '+ inttostr(daten1.count));
    ListBox.Items.Add('Nach Merge Data2.Count: '+ inttostr(daten2.count));

    Label1.Caption := 'Merge...Done ... Sort';
    Daten1.Sort(??????????????)


end;
Wem hilft ist gut, wem nicht auch gut und die Sikusion endet dann erstmal hier
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 06:24 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