Autor Beitrag
nocki
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Fr 19.03.10 14:24 
user profile iconnocki hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

:welcome: im Forum!

user profile iconnocki hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 20

-
Delphi 5
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 20

-
Delphi 5
BeitragVerfasst: Fr 19.03.10 20:35 
Position ist unter D5 ein Longint - max. 2 GB.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Fr 19.03.10 20:42 
Position ist unter D5 ein signed Longint - max. 2 GB.

:lol:

_________________
"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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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:

ausblenden 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 user profile iconGausi: Delphi-Tags hinzugefügt
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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