Auf große Dateien (>4GB) wahlfrei zugreifen



  • Hallo Leute,

    ich bin auf der Suche nach einer Möglichkeit, Dateien, die größer als 2^32 Bytes groß sind, wahlfrei zuzugreifen. Kennt jemand von euch Standard-Bibliotheken, die sowas leisten?
    fseek() kann leider nur mit der Parametergröße long operieren. In meinem Fall bräuchte ich eine Funktion mit einem Datentyp, der einen größeren Wertebereich abdecken kann.

    Danke für eure Hinweise
    Gruß,
    Joe



  • Unter Unix gibt es Funktionen wie zum Bespiel fseeko, die einen off_t und keinen long nimmt. off_t kann aber 64 Bit groß sein. Näheres solltest du in der manpage von fseeko finden.



  • Auf Windows würd ich einfach filemapping beutzen (http://www.flipcode.com/articles/article_filemapping.shtml)..



  • Hallo,

    funktioniert auch mit der STL:

    fstream::streampos LastFilePos = File.tellp();
    
          __int64 MyPos = 0xF00000000;
          fstream::streampos NewFilePos(LastFilePos.state(), MyPos);
          File.seekg(NewFilePos);
          File.read(&Data[Size], MaxSize);
    
      File.seekp(LastFilePos);
    


  • seek schrieb:

    Hallo,

    funktioniert auch mit der STL:

    fstream::streampos LastFilePos = File.tellp();
    
          __int64 MyPos = 0xF00000000;
          fstream::streampos NewFilePos(LastFilePos.state(), MyPos);
          File.seekg(NewFilePos);
          File.read(&Data[Size], MaxSize);
    
      File.seekp(LastFilePos);
    

    Die STL kennt __int64?



  • Er meint, das man weiter mit den Streams arbeiten kann. Aber unter VC++ ist long wie int ein 32bit Typ. Da aber die Streams long benutzen, weil long eigentlich 64bit sein kann (ist ja nicht im ISO festgelegt), sollte man __int64 vom VC++ benutzen, dann funktioniert es auch mit größer 4 GByte.



  • Nicht ganz. seek() akzeptiert nur einen 32bit Offset, wenn man die Position setzen will muss man ein Object vom Type streampos übergeben. Der Konstruktor von streampos: fpos(_Statetype _State, fpos_t _Fileposition) und fpos_t: typedef __int64 fpos_t. Das ganze ist auf meinem Mist gewachsen, ich hoffe es ist auch legal.



  • life schrieb:

    Auf Windows würd ich einfach filemapping beutzen

    Ich nicht. Das ständige Mappen und Unmappen braucht auch seine Zeit. Und man muss es machen, weil die gesamte Datei unter Win32 nicht in den Adressraum passt. Unter Win64 natürlich schon...



  • du liest einfach genauso wie bei denem fstream ab nem bestimmten offset (man kann da halt offset bis 2^64 definieren)..



  • Danke mal für eure Antworten.
    Was ich gerade gesehen hab:

    The Microsoft run-time library defines the following standard types.
    fpos_t (long integer, __int64, or structure, depending on the target platform)

    Demnach sollte der Aufruf mit

    int fsetpos( 
       FILE *stream,
       const fpos_t *pos 
    );
    

    eigentlich funktionieren

    Gruß,
    Joe



  • Der Standard gibt die keinerlei Garantie. Unter 32 Bit Systemen solltest Du Dateien bis 2GB schreiben können, danach ist Sense.

    Wenn Du das ganze garantiert und sicher haben willst, nimm die BS-API. Unter Windows ist der einzige Weg, der auch garantiert funktioniert übers FileMapping. Mit ReadFile und SetFilePosEx geht es zwar wohl, allerdings wird das nirgends in der MSDN als funktionierend erwähnt.


Anmelden zum Antworten