Autor |
Beitrag |
nocki
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 19.03.10 13:48
Hallo,
ich bin neu in diesem Forum und habe nur mäßige Delphi-Kenntnisse.
Vielleicht kann mir einer der Experten bei der Lösung meines Problems helfen (ich arbeite mit Delphi 7 unter Win XP):
Nach meiner Kenntnis kann ich mit Delphi7 nur Dateien verarbeiten, die kleiner als 2 GB sind, da seek und FilePos jeweils mit 32-bit-Integers (longint) arbeiten. Ich möchte aber Dateien verarbeiten, die größer als 2 GB sind.
- Gibt es Routinen, welche die 32 bit ganz ausnutzen (also mit vorzeichenlosen Integers arbeiten) und damit Dateigrößen bis 4 GB erlauben?
- Gibt es evtl. sogar Routinen, die mit 64-bit-Integers arbeiten und damit sogar Dateien >4 GB verarbeiten können?
Vielen Dank für Eure Hilfe
nocki
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Fr 19.03.10 14:24
nocki hat folgendes geschrieben : | Hallo, |
 im Forum!
nocki hat folgendes geschrieben : | Nach meiner Kenntnis kann ich mit Delphi7 nur Dateien verarbeiten, die kleiner als 2 GB sind, da seek und FilePos jeweils mit 32-bit-Integers (longint) arbeiten. |
Not true.
TFileStream kann seit Delphi 4(?) mit int64 umgehen, damit wäre das also dein zweiter Fall.
Auch die WinAPI-Wrapper FileSeek, FileWrite, FileRead etc. existieren in überladenen Versionen, die int64 verwenden.
Was Borland nicht gemacht hat: GetFileSize einen solchen Wrapper verpassen. Da müss man selber was schrauben.
Aber wie gesagt: TStream kann das, also kein Grund da unnötigen Aufwand zu betreiben
cu
Martok
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
nocki 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 19.03.10 14:54
Vielen Dank für die schnelle Hilfe,
dieser Hinweis war sehr hilfreich. Ich wußte nicht, daß es solche Routinen mit int64 bereits seit langer Zeit gibt und werde es nun mit TFilestream probieren.
Gruß Nocki
|
|
kurt59
      
Beiträge: 20
-
Delphi 5
|
Verfasst: Fr 19.03.10 18:14
Zum Testen wurde eine Datei mit 6GB geöffnet und dann versucht
den Dateizeiger auf eine Position >2GB zu setzen.
Bei Delphi 5 kommt mit fstream.position:=4300000000 eine Fehlermeldung:
Exception der Klasse ERangeError 'Fehler bei Bereichsüberprüfung'
Das war's - bis 2GB geht es.
Kurt
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Fr 19.03.10 18:29
Ah, okay. Dann war mein (?) oben doch berechtigt, und die Änderung wohl erst in D6 oder D7 passiert.
Danke fürs erforschen 
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Fr 19.03.10 18:45
Grad nachgesehen: Position ist unter D5 noch ein Longint, also max. 4 GB.
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
kurt59
      
Beiträge: 20
-
Delphi 5
|
Verfasst: Fr 19.03.10 20:35
Position ist unter D5 ein Longint - max. 2 GB.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Fr 19.03.10 20:42
Position ist unter D5 ein signed Longint - max. 2 GB.

_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
nocki 
Hält's aus hier
Beiträge: 4
|
Verfasst: Mo 22.03.10 12:55
Hallo,
ich habe (unter D7, WinXP) mal eine 5-GB-Datei erzeugt und dann versucht, sie mittels TFilestream zu lesen. Bis zur 2GB-Grenze klappt alles, dann nicht mehr:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.Button2Click(Sender: TObject); var f: TFileStream; p,p1: int64; const GB2m1:int64=2*int64(1024)*1024*1024-1; GB2 :int64=2*int64(1024)*1024*1024; GB2p1:int64=2*int64(1024)*1024*1024+1; begin f :=TFileStream.Create('d:\Test',fmOpenRead); p:=-2; p1:=-2; p:=f.Seek(GB2m1,soFromBeginning); p1:=f.Position; MessageDlg('p,p1='+inttostr(p)+','+inttostr(p1), mtInformation, [mbOk], 0); p:=-2; p1:=-2; p:=f.Seek(GB2,soFromBeginning); p1:=f.Position; MessageDlg('p,p1='+inttostr(p)+','+inttostr(p1), mtInformation, [mbOk], 0); p:=-2; p1:=-2; p:=f.Seek(GB2p1,soFromBeginning); p1:=f.Position; MessageDlg('p,p1='+inttostr(p)+','+inttostr(p1), mtInformation, [mbOk], 0); f.Free; end; |
Das erste seek liefert die erwarteten Werte: 2147483647,2147483647.
Die nächsten beiden seeks liefern jedoch -1,2147483647.
Wo liegt der Fehler?
nocki
Moderiert von Gausi: Delphi-Tags hinzugefügt
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 22.03.10 19:41
Wenn Du derlei große Dateien via 32 Bit machen willst, solltest Du mal soCurrent probieren. (Sprung relativ zur aktuellen Position). Beachte, dass die angegebenen Offsets wahrscheinlich nicht stimmen werden.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
nocki 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 26.03.10 15:26
Danke für den Tipp, BenBE.
ich hab es mal mit soCurrent probiert - das klappt tatsächlich, wenn man nur max. 2 GB weite Sprünge macht.
Viel besser ist aber die Benutzung von TFilestream.Position. Einfach Position einen neuen Wert zuweisen, dann read aufrufen - fertig.
Auf das Einfachste kommt man eben zuletzt.
Vielen Dank für alle Hinweise
nocki
|
|
|