Dateien über 4GB



  • Hallo,

    ich bin auf der Suche nach einer Möglichkeit in einem C++ Programm auf Datein mit einer größe von über 4 GB zuzugreifen. Die STL kann leider nur mit maximal 2GB umgehen.
    Bietet die WinAPI eine solche Möglichkeit?

    Vielen Dank im Voraus,
    Apophis



  • Lord Apophis schrieb:

    Die STL kann leider nur mit maximal 2GB umgehen.

    Echt? Bei mir klappt das einwandfrei auch mit 6 GB (und noch größer) Dateien.

    Kann sein, dass es unterschiedliche Versionen gibt, oder dass es nicht Standard ist, aber bei mir klappt's. Du musst nur kein int nehmen sondern __int64 für den Zugriff.

    mfg.



  • CreateFile/ReadFile/WriteFile/SetFilePointerEx/CloseHandle
    Oder eben die i64-Funktionen aus der CRT...



  • Also bei mir kann der (i/o)fstream nur maximal 2GB, der arbeitet intern wohl mit 32 Bit.
    Wo finde ich denn die i64 Funktionen?



  • Lord Apophis schrieb:

    Also bei mir kann der (i/o)fstream nur maximal 2GB, der arbeitet intern wohl mit 32 Bit.
    Wo finde ich denn die i64 Funktionen?

    Welchen Compiler benutzt du? Wie sieht dein Code aus?

    mfg.



  • Also, das lesen/schreiben von Dateien hat primär nichts mit grossen Dateien zu tun. Probleme können eigentlich nur entstehen, wenn Du "seek" und "tell" operationen ausführst. Und natürlich wenn Du FAT32 anstelle von NTFS verwendest 😉

    64-bit Funktionen sind z.B. "_lseeki64" und "_telli64" für WinAPI: SetFilePointerEx



  • Welchen Compiler benutzt du? Wie sieht dein Code aus?

    Ich verwende DevCpp unter 32Bit WinXP.

    Ich hab das grad nochmal getestet, das Lesen über der 2GB Marke scheint zu gehen, nur liefert "tellg" dann -1 und "_telli64" ist nicht deklariert. Muss ich dazu eine andere Headerdatei einschließen?

    vielen Dank,
    Apophis



  • Lord Apophis schrieb:

    Welchen Compiler benutzt du? Wie sieht dein Code aus?

    Ich verwende DevCpp unter 32Bit WinXP.

    Ich hab das grad nochmal getestet, das Lesen über der 2GB Marke scheint zu gehen, nur liefert "tellg" dann -1 und "_telli64" ist nicht deklariert. Muss ich dazu eine andere Headerdatei einschließen?

    vielen Dank,
    Apophis

    Ich mach das so:

    __int64 size = fs.tellg();
    

    und das klappt. Ich hab Code::Blocks, aber mit Dev-Cpp müsste es eigentlich auch gehen.

    mfg.



  • Nein, bei mir geht das leider nicht so.
    tellg liefert ab einem offset von 2147483456 (0x7FFFFF40) (das sind noch nicht einmal 2GB (0x7FFFFFFF)) -1.
    Ich benötige wohl diese expliziten 64Bit Funktionen.



  • Nimm doch SetFilePointerEx oder SetFilePointer mit FILE_CURRENT und offset 0! Dann bekommst Du die aktuelle Position zurück!
    Das ist das was intern "ftell" macht...



  • Ich will den code möglichst portabel halten, gehören "_lseeki64" und "_telli64" wirklich zur C-CRT? Wenn ja nehme ich lieber die.
    Im C/C++ forum wurde mir einmal gesagt, die STL käme mit so großen Dateien wohl nich so gut klar (fstream) daher habe ich nach einer Lösung in der WinAPI gefragt, wenn es nun doch etwas anderes gibt nehme ich natülich lieber das 😉

    mfg
    Apophis



  • AFAIK gibt es bei der C-CRT keine Funktionen für Dateien > 4 GB... somit kannst Du schon mal nicht eine "Standard" Funktion nehmen.



  • Aha, schade.

    Dann habe ich aber noch mal eine Frage am Rande:
    Auf einem 64Bit System ist int sicher meistens 64Bit, ist der fstream dort in der Lage auf größere dateien (also theorethisch bis 8 EB) zuzugreifen?

    mfg
    Apophis



  • Bei MS ist "int" auf als x64 übersetzt auch 32-Bit...
    Siehe:
    http://msdn2.microsoft.com/s3f49ktz



  • Ok, bei M$ aber z.B. der Borland C++ Builder 6 nimmt int als 64 Bit auf einem 64 Bit System. Vor allem würde mich interessieren wie das bei mingw/gcc ist.

    mfg



  • Lord Apophis schrieb:

    Ok, bei M$ aber z.B. der Borland C++ Builder 6 nimmt int als 64 Bit auf einem 64 Bit System.

    Mich würde vor allem interessieren, ob es hierfür einen eindeutigen Standard gibt...



  • Ich glaube nicht.
    In "Die C++ Programmiersprache" (Ja, ich hab die deutsche Version) steht nichts von einem Standard, ist alles implementierungsspezifisch.
    Ich will nur wiss, ob fstream wenn int 64 Bit ist mit großen Files klar kommt.

    mfg



  • Lord Apophis schrieb:

    Ich will nur wiss, ob fstream wenn int 64 Bit ist mit großen Files klar kommt.

    Das sollte eigentlich auch so damit klar kommen. Versuch mal folgenden Code:

    #include <iostream>
    #include <fstream>
    
    int main() {
        using namespace std;
        cout << "Filename: ";
        string filename;
        getline(cin, filename);
        ifstream file(filename.c_str(), ios::binary);
        if(!file.is_open()) {
            cout << "File not found!" << endl;
            return 1;
        }
        file.seekg(0, ios::end);
        unsigned long long size = file.tellg();
        cout << "sizeof(unsigned long long) == " << sizeof(unsigned long long) << endl;
        cout << "Size: " << size << endl;
        return 0;
    }
    

    Bei mir klappt das, und sollte unter Linux mit dem gcc eigentlich auch gehen.

    mfg.



  • Das funktioniert bei mir leider nicht.
    Die Ausgabe lauet: "Size: 18446744073709551615"

    also 0xFFFFFFFFFFFFFFFF, signed ist das -1 was bei mir immer rauskommt wenn ich über 2GB mit seekg oder tellg arbeite.

    Aber trotzdem Danke.

    mfg
    Apophis


Log in to reply