[C++] große Dateien (>2 GB) lesen

Onkel Schuppig

Erfahrenes Mitglied
Hi,
ich bin kürzlich auf die Grenzen der Funktionen
Code:
long ftell()
int fseek(FILE*, long, int)
gestossen.
Man sieht, dass Positionen außerhalb des Zahlenbereichs einer long-integer-Variable nicht erreicht werden können, was bedeutet, dass Dateien > 2 GB nicht vollständig lesbar sind.

Gibt es mittlerweile etwas "moderneres"? Muss aber portabel sein (Windows, Unix, Linux, ...).

Dann habe ich noch eine unerwartete schlechte Erfahrung gemacht:
Code:
FILE* p_file = fopen("riesige_datei.txt", "r");
char buffer[256];
while(fgets(buffer, 255, p_file));
ist ca. 10-mal schneller als
Code:
ifstream ifs("riesige_datei.txt");
char buffer[256];
while (ifs.getline(buffer, 255));
Faktor 10 ist bei solch großen Dateien erheblich. Deshalb will ich nicht unbedingt streams verwenden.

mfG
OS
 
Hmm, ich stelle mit fseek nur fest, wie groß die Datei ist
Code:
fseek(p_file, 0L, SEEK_END);
Das bekomme ich auch mit 2x fseek nicht hin, weil ich ... nicht kenne, oder?
 
Mir fällt da jetzt noch die boost library ein.
Hab aber leider selber nicht so viel Erfahrung mit der Library.
Es gibt aber IMHO 64bit Positionierungen.
Vielleicht bringts dich weiter...

Hier: Boost Library

Gruß, Christian
 
:p :p :p :p :p :p :p :p
IMHO beduetet "In My Humble Opinion"
auf deutsch: Meiner (bescheidenen) Meinung nach
also in etwa: "ich bin mir da nicht so ganz sicher"
 
Hi.

Also unter Linux kannst du fseeko und ftello verwenden. Der Unterschied ist, das das offset Argument der Funktionen nicht long ist, sondern off_t.

Wenn man dann
Code:
#define  _FILE_OFFSET_BITS 64
verwendet, ist off_t ein 64bit Typ.

Gruß
 
Hmm, ich stelle mit fseek nur fest, wie groß die Datei ist
Code:
fseek(p_file, 0L, SEEK_END);
Das bekomme ich auch mit 2x fseek nicht hin, weil ich ... nicht kenne, oder?

Sorry hab mich wohl ein wenig unklar ausgedrückt.
Was ich meinte das du zuerst den Pointer auf die aktuelle Position auf 2GB setzten kannst,
und dann von da aus weiter lesen.
Sprich erst fseek(FILE, 2147483648, SEEK_SET), dann steht der Ponter an der der
2147483648. Byte-Stelle in der Datei, und dann von da aus (Parameter SEEK_CUR anstatt SEEK SET)
weiterlesen, das meinte ich mit den Punkten:
fseek(FILE, 10 (oder 20 oder 100 oder was-auch-immer), SEEK_CUR);

Falls noch nicht klar, mal als Code: (Ich weiß ich drück mich kompliziert aus :-) )
Code:
long 2GB_Grenze = 2147483648;

fseek(FILE, 2GB_Grenze, SEEK_SET); // Pointer steht jetzt bei 2GB
fseek(FILE, 100000, SEEK_CUR); //Jetzt steht der Pointer bei 2GB und 100 KByte

Falls das nicht geht (ich kanns nich grad nicht ausprobieren hab keine File die so groß ist)
weiß ich auch nicht.

Ich kenn nur für unter Windows noch die Funktion ReadFile() bzw ReadFileEx() - evtl. können die das.
 
Habe mittlerweile von den Funktionen fseek64, fopen64 und ftell64 gehört.
Scheint es aber nur in der Linux- und Unixwelt zu geben. Unglücklicherweise habe ich Windows. ;)
 
Zurück