Kurz gesagt: Cross-Operating-System, Unterstützung großer Dateien in C ist entsetzlich.
Ziel: Ich versuche, "one way" (höchstwahrscheinlich makrobasiert) zu haben, damit 32-bit UND 64-bit große Dateien unterstützen können. Idealerweise mit typedefs, # ifdefs, # (n) definiert, usw. könnte ein Makro-Wrapper grundlegende Unterstützung großer Dateien in Form einer # include-Bibliothek oder eines Satzes definierter Makros ermöglichen.
Forschung: POSIX-Dateioperationen haben sich unter BSD / Mac / Linux für 32- und 64-Bit-IO mit Dateien größer als die typische 2 ^ 31-Größe bewährt, aber sogar mit Clam oder Mingw unter Windows Ich kann diese Anrufe wegen der dummen Implementierung von POSIX von M $ nicht nutzen (wenn wir das so nennen wollen ...). Ich bin in Richtung auf die Verwendung von CreateFile (), ReadFile (), WriteFile () unter Windows, aber das ist völlig anders als POSIX-open () / read () / write () / close () / etc in Bezug auf Methodik und Datentypen verwendet.
Frage: Nachdem ich meinen Kopf gegen meine Tastatur und mehrere Textbücher geschlagen habe, habe ich beschlossen, euch alle zu fragen: Wie geht's Jungs / Mädels, die Cross OS Datei fertigstellen? I / O, die große Dateien unterstützt?
P.S. Ich habe Forschungslinks:
So sehr wir alle es hassen, M $ wegen ihrer schlechten Standardkonformität zu hassen, war diese Sache tatsächlich die Schuld des ISO C Komitees. Ursprünglich verwendeten sie size_t für alle Dateiparameter, aber size_t wurde basierend auf der ALU / Speicher-Architektur gewählt und nicht auf den Betriebssystem-Dateiverarbeitungsfähigkeiten basiert. Als alle auf 64-Bit-CPUs umschalteten, blieb MS mit einer 32-Bit-Länge stecken, die sie vollkommen ausführen durften und trotzdem konform waren, aber jetzt sind ihre Dateien größer als ihre größten arithmetischen Typen.
Beachten Sie, dass dies in C99 schließlich gelöst wurde, aber MSVC C99 Unterstützung ist im Grunde nicht existent.
Intern verwenden sie jedoch tatsächlich einen 64-Bit-Zeiger zum Verfolgen Ihres Standorts in der Datei. Das Problem ist wegen der unglücklichen cstdlib-API, die Sie nicht "fseek" oder "ftell" für etwas verwenden können, das größer als 32 Bits ist.
Um zu demonstrieren, dass Windows tatsächlich einen 64-Bit-Dateizeiger verwendet, funktioniert dieser Code tatsächlich wie erwartet, wenn er mit MSVC ++ kompiliert wird, und erzeugt eine 40-GB-Datei (nicht signiert lang ist 32-Bit) auf Ihrer Festplatte. p> %Vor%
Wie hilft Ihnen das? Nun, MS bietet eine eigene Nicht-Standard-API, die 64-Bit fseek () und ftell () erlaubt
Sie können den Dateizeiger jedoch auch mit regulärem fseek () bewegen, indem Sie in Inkrementen vorgehen ... im Grunde genommen:
%Vor%Es wird den Dateizeiger effektiv auf die 10-GB-Marke verschieben.
Mit ftell () wirst du wahrscheinlich gefickt, ohne die MS API dafür zu benutzen.
TL; DR - fopen (), fread () und fwrite () funktionieren auf MSVC mit großen Dateien & gt; 2GB, aber ftell () und fseek () nicht, weil die API nicht richtig entworfen wurde.
Sie sind nicht vollständig ohne Optionen in Windows:
Unter Linux können Sie -D_FILE_OFFSET_BITS=64
(ein #define _FILE_OFFSET_BITS 64
könnte funktionieren, nicht sicher) und fseeko
/ ftello
verwenden. Viele Systeme haben auch fseeko64
und ftello64
), die unabhängig von diesem #define
funktionieren.