Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem beim einlesen einer Datei in einen Stream (https://www.delphipraxis.net/90196-problem-beim-einlesen-einer-datei-einen-stream.html)

Chilled86 13. Apr 2007 09:31


Problem beim einlesen einer Datei in einen Stream
 
Hi Leute,
hab leider wieder ein kleines Problem. Ich will eine Datei in einen Stream einlesen. Meine Pfadangabe stimmt auf jeden Fall, hab ich bereits gecheckt. Wenn ich es ausführe bekomme ich eine Exception der Klasse ERangeError "Fehler bei Bereichsprüfung". Ich kenne mich mit Streams nicht so gut aus und habe das ganze aus einem Tutorial. Kann mir einer sagen was ich falsch mache?


Delphi-Quellcode:
type
  TDatensatz = record
    ID: integer;
    Name: AnsiString;
  end;
  TDatenArray = array of TDatensatz;




procedure TForm1.Button1Click(Sender: TObject);
var
  Daten: TDatenArray;
  Stream: TStream;
  I: integer;
  Len: LongInt;
begin
  Stream := TFileStream.Create(Sett_QIPPath + '\Users\' + Sett_ICQNumber + '\History\' + HistoryData[2].FileName, fmOpenRead);
  try
    Stream.Read(Len, SizeOf(Len));
    SetLength(Daten, Len);
    for I := 0 to Len - 1 do begin
      Stream.Read(Daten[I].ID, SizeOf(Daten[I].ID));
      Stream.Read(Len, SizeOf(Len));
      SetLength(Daten[I].Name, Len);
      Stream.Read(PChar(Daten[I].Name)^, Len);
    end;
  finally
    Stream.Free;
  end;
  //ShowData(Daten);
end;

ste_ett 13. Apr 2007 09:34

Re: Problem beim einlesen einer Datei in einen Stream
 
An welcher Stelle tritt der Fehler auf?

Chilled86 13. Apr 2007 09:36

Re: Problem beim einlesen einer Datei in einen Stream
 
Weiß ich nicht genau, wenn ich auf Anhalten gehe, zeigt er mir leider nicht die Stelle an, bei der das ganze passiert.

CCRDude 13. Apr 2007 09:37

Re: Problem beim einlesen einer Datei in einen Stream
 
Der Typecast zum PChar erscheint mir etwas umständlich... versuch doch stattdessen mal
[i]Stream.Read(Daten.Name[1], Len);

PS: Warum ist Len ein LongInt und kein LongWord/Cardinal? Erwartest Du negative Zeichenlängen? ;)

PPS: Wenn man mit F7/F8 durchsteppt, merkt man doch, wann der Fehler erscheint ;)

Chilled86 13. Apr 2007 09:42

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von CCRDude
Der Typecast zum PChar erscheint mir etwas umständlich... versuch doch stattdessen mal
[i]Stream.Read(Daten.Name[1], Len);

^^ Lässt Delphi und mein Tool crashen... Totalabsturz :shock:


Zitat:

Zitat von CCRDude
PS: Warum ist Len ein LongInt und kein LongWord/Cardinal? Erwartest Du negative Zeichenlängen? ;)

Stimmt auch wieder



Zitat:

Zitat von CCRDude
PPS: Wenn man mit F7/F8 durchsteppt, merkt man doch, wann der Fehler erscheint ;)

Hier stürzt das Teil ab
Delphi-Quellcode:
SetLength(Daten, Len);

***EDIT***
SizeOf gibt einen SmallInt zurück, kanns sein dass der zu klein is? Wenn ja, wie kann ich das denn anders lösen?

TeronG 13. Apr 2007 09:46

Re: Problem beim einlesen einer Datei in einen Stream
 
Hab mit Streams auch noch net so viel gemacht aber evtl. isses ja nur:

var
Stream: TStream;
begin
Stream := TFileStream.Create(....);

:gruebel:

BTW: hab mal gelesen, daß man aus gründern der Kompatibilität keine Generischen Typen Speichern soll. (Integer = Generisch -> nicht in jeder Delphiversion gleich)

EDIT: BTW: Sind die roten Kästen deaktiviert!?

Gruber_Hans_12345 13. Apr 2007 09:52

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von Chilled86
Hier stürzt das Teil ab
Delphi-Quellcode:
SetLength(Daten, Len);

dann zeig dir mal den eingelesenen wert von Len an, ich vermute mal, das Len ein ungültiger wert ist (kleiner 0 oder viel zu groß)

CCRDude 13. Apr 2007 09:56

Re: Problem beim einlesen einer Datei in einen Stream
 
Da TFileStream ein Enkel von TStream ist, dürfte das eigentlich kein Problem bedeuten.

Stream.Read(stringvariable[1], stringlaenge) benutze ich vielfach problemlos.

SizeOf(was?) gibt einen SmallInt zurück?

Zitat:

Zitat von TeronG
BTW: hab mal gelesen, daß man aus gründern der Kompatibilität keine Generischen Typen Speichern soll. (Integer = Generisch -> nicht in jeder Delphiversion gleich)

Könnte ein Problem ergeben, sobald es einen Delphi-Compiler für 64 bit gibt. Dummerweise ist das noch in weiter Ferne :? Aber stimmt, daran sollte man jetzt schon denken.

Zitat:

Zitat von Chilled86
Hier stürzt das Teil ab
Delphi-Quellcode:
SetLength(Daten, Len);

Was sagen denn die lokalen Ausdrücke (oder die Watch), wie groß Len zu diesem Zeitpunkt ist? Wenn es negativ wäre, wäre das ein guter Grund für den Fehler bei der Bereichsprüfung (siehe auch zwischenzeitlich erschienener anderer Beitrag).

Warum aber bei Dir SizeOf(Len) = SizeOf(SmallInt) und nicht SizeOf(LongInt) (wenn ich das jetzt richtig verstanden habe) kann ich auch nicht beantworten :shock:

Chilled86 13. Apr 2007 09:59

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von Gruber_Hans_12345
dann zeig dir mal den eingelesenen wert von Len an, ich vermute mal, das Len ein ungültiger wert ist (kleiner 0 oder viel zu groß)

Len ist 757935405

lizardking 13. Apr 2007 10:03

Re: Problem beim einlesen einer Datei in einen Stream
 
Delphi-Quellcode:
    Stream.Read(Len, SizeOf(Len));
An der Stelle sollte es eigentlich schon knallen. Versuch mal

Delphi-Quellcode:
    Stream.Read(@Len, SizeOf(Len));
;)

CCRDude 13. Apr 2007 10:05

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von lizardking
An der Stelle sollte es eigentlich schon knallen. Versuch mal
Delphi-Quellcode:
    Stream.Read(@Len, SizeOf(Len));

Wieso? So intelligent ist Delphi schon, die Adresse zu verwenden ist da keineswegs notwendig (habe ich auf zwei Seiten voller gegrepter .Read-Aufrufe nie verwenden müssen ;) ).

Chilled86 13. Apr 2007 10:07

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von lizardking
An der Stelle sollte es eigentlich schon knallen. Versuch mal

Delphi-Quellcode:
    Stream.Read(@Len, SizeOf(Len));
;)

"Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden" :wall:



***EDIT***
Len ist irgendwie immer gleichgroß, selbst wenn ich im Stream ne andere Datei öffne

CCRDude 13. Apr 2007 10:14

Re: Problem beim einlesen einer Datei in einen Stream
 
Deswegen sag ich ja, daß die Adresse unnötig ist ;)

Und eine Größe von $2D2D2D2D erscheint mir heftig, da bin ich mir unsicher, ob dynamische Arrays diese Größe überhaupt unterstützen? Außerdem erscheint mir $2D2D2D2D auch nicht wie das typische Größenfeld. Hat die Datei vielleicht am Anfang noch einen Header? Ich würd vorschlagen Du liest Dir den Anfang der Datei erstmal mit einen Hexeditor durch, bevor Du weiter Fehler im Code suchst ;)

Chilled86 13. Apr 2007 10:19

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von CCRDude
Deswegen sag ich ja, daß die Adresse unnötig ist ;)

Und eine Größe von $2D2D2D2D erscheint mir heftig, da bin ich mir unsicher, ob dynamische Arrays diese Größe überhaupt unterstützen? Außerdem erscheint mir $2D2D2D2D auch nicht wie das typische Größenfeld. Hat die Datei vielleicht am Anfang noch einen Header? Ich würd vorschlagen Du liest Dir den Anfang der Datei erstmal mit einen Hexeditor durch, bevor Du weiter Fehler im Code suchst ;)

Die Datei hat keinen Header. Ist ne stink normale TXT Datei

CCRDude 13. Apr 2007 10:29

Re: Problem beim einlesen einer Datei in einen Stream
 
Und warum versuchst Du dann, Binärfelder für Längen aus einer TEXT-Datei auszulesen? :shock:

Las mich raten... die ersten 4 Zeichen der Textdatei sind "----" - das entspricht dann Deiner "Länge"...

Du vermischt hier dann wohl zwei Sachen: typisierte Dateien mit Textdateien. Das wär auch "klassisch" ohne Streams (file of record vs. textfile) nicht machbar. Du mußt dann hier byteweise bis #13 bzw. #13#10 oder #10 auslesen etc...

PS: Wo ich mir das oben näher ansehe, merke ich auch, daß es um ICQ-Logs geht? Ja, die sind wahrscheinlich wirklich Text... da Du geschrieben hast, daß Du Dich mit Streams nicht genau auskennst, kennst Du ja vielleicht normale Textdateien wenigstens? Dann würde ich die empfehlen... Hier mal ein DelphiBasics-Beispiel.

Chilled86 13. Apr 2007 10:32

Re: Problem beim einlesen einer Datei in einen Stream
 
Zitat:

Zitat von CCRDude
Und warum versuchst Du dann, Binärfelder für Längen aus einer TEXT-Datei auszulesen? :shock:

Las mich raten... die ersten 4 Zeichen der Textdatei sind "----" - das entspricht dann Deiner "Länge"...

Du vermischt hier dann wohl zwei Sachen: typisierte Dateien mit Textdateien. Das wär auch "klassisch" ohne Streams (file of record vs. textfile) nicht machbar. Du mußt dann hier byteweise bis #13 bzw. #13#10 oder #10 auslesen etc...

:wiejetzt: Das könnte natürlich mein Problem sein :oops: Hast du ein Tutorial wie das ganze funzt?

TeronG 13. Apr 2007 10:39

Re: Problem beim einlesen einer Datei in einen Stream
 
Wie gesagt ich bin kein Stream-Experte aber warum verwendest du nicht TMemoryStream? Das ding hat nämlich ein .LoadFromFile ... :gruebel:

CCRDude 13. Apr 2007 10:43

Re: Problem beim einlesen einer Datei in einen Stream
 
Naja, einen TMemoryStream kann man als Cache dazwischenschalten, aber prinzipiell würde ich fast nie TMemoryStream.LoadFromFile verwenden, solange die Größe der verwendeten Dateien beliebig sein kann. Eher blockweise von TFileStream nach TMemoryStream umkopieren, aber das ist für nen Streamneuling nicht wirklich das wahre...

Ein wirklich simples Beispiel, das eine einzelne Zeile in eine Textdatei schreibt und danach alle Zeilen dieser Datei nacheinander ausliest, ist schon in meinem PS darüber verlinkt. Nochmal grob das zeilenweise auslesen zusammengefasst:

Delphi-Quellcode:
var tf: TextFile;
    sLine: string;
begin
   AssignFile(tf, 'c:\meincqlog.txt');
   while not EoF(tf) do begin
      ReadLn(tf, sLine);
      DoSomethingWithText(sLine);
   end;
   CloseFile(tf);
end;
Ist zwar nicht bis ins letzte objektorientiert, aber manchmal muss man das mit der OO ja auch nicht übertreiben ;)

Chilled86 13. Apr 2007 10:49

Re: Problem beim einlesen einer Datei in einen Stream
 
DANKE FÜR EURE HILFE!!!!
habs hinbekommen, und sorry dass ich als so dumme Fragen stell, bin halt noch Anfänger. :coder:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:01 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