2009-06-23 13 views
12

ich in Integer-Überlauf am Laufen, aber ich glaube, ich war falsch, weil es scheint, dass ftell64 und fseek64 sind nicht verfügbar. Ich habe gesucht und viele Websites scheinen mit lseek mit dem off64_t-Datentyp zu referenzieren, aber ich habe keine Beispiele gefunden, die auf etwas verweisen, das fseek entspricht. Im Moment sind die Dateien, die ich lese, 16GB + CSV-Dateien mit der Erwartung von mindestens doppelt so viel.Sucht und große Dateien in einem Linux-C Lesen ++ Anwendung

Ohne externe Bibliotheken, was ist die einfachste Methode, um eine ähnliche Struktur wie mit dem fseek/ftell Paar zu erreichen? Meine Anwendung arbeitet jetzt mit den Standard-GCC/G ++ - Bibliotheken für 4.x.

Antwort

24

fseek64 ist eine C-Funktion. Um es verfügbar zu machen, müssen Sie _FILE_OFFSET_BITS = 64 definieren, bevor Sie die System-Header einfügen, die mehr oder weniger definieren, dass fseek tatsächlich fseek64 ist. Oder mach es in den Compiler-Argumenten z.B. gcc -D_FILE_OFFSET_BITS = 64 ....

http://www.suse.de/~aj/linux_lfs.html hat eine große overviw von Unterstützung für große Dateien auf Linux:

  • Kompilieren Sie Ihre Programme mit "gcc -D_FILE_OFFSET_BITS = 64". Dies zwingt alle Dateizugriffsaufrufe, die 64-Bit-Varianten zu verwenden. Verschiedene Arten ändern sich auch, z. off_t wird off64_t. Es ist daher wichtig, immer die richtigen Typen zu verwenden und z. int statt off_t. Für die Portabilität mit anderen Plattformen sollten Sie getconf LFS_CFLAGS verwenden, das auf Linux-Plattformen -D_FILE_OFFSET_BITS = 64 zurückgibt, aber etwas anderes z. Solaris. Zum Verknüpfen sollten Sie die Link-Flags verwenden, die über getconf LFS_LDFLAGS gemeldet werden. Auf Linux-Systemen benötigen Sie keine speziellen Link-Flags.
  • Definieren Sie _LARGEFILE_SOURCE und _LARGEFILE64_SOURCE. Mit diesen Definitionen können Sie die LFS-Funktionen wie open64 direkt verwenden.
  • Verwenden Sie das O_LARGEFILE-Flag mit open, um mit großen Dateien zu arbeiten.
+0

Also, ich folgte Ihren Anweisungen und alles kompiliert Datei. Aber ich scheine immer noch einen Überlauf zu bekommen. Wie würden Sie den Parameter O_LARGEFILE mit fopen64 verwenden? –

+0

Wenn Sie mit -D_FILE_OFFSET_BITS = 64 kompilieren, wird O_LARGEFILE automatisch geliefert. Dies ist keine Standardflagge. Es wird unter Linux verwendet, um zu verfolgen, ob die Datei mit großen Dateischnittstellen geöffnet wurde. – mark4o

+0

Sie haben die Frage als C++ gestellt, verwenden Sie C-Datei-Operationen mit C++ - Streams und/oder verwenden Sie nur die C-API? Haben Sie auch einen Testcode, um das Verhalten zu reproduzieren? Es ist von größter Wichtigkeit, dass Sie die richtigen Typen verwenden, die sich mit Längen/Offsets befassen. – nos

5

fseek64() ist kein Standard, die Compiler-Dokumentation sollte Ihnen sagen, wo Sie es finden können.

Haben Sie versucht fgetpos und fsetpos? Sie sind für große Dateien ausgelegt, und die Implementierung verwendet normalerweise einen 64-Bit-Typ als Basis für fpos_t.

2

Verwenden Sie fsetpos(3) und fgetpos(3). Sie verwenden den fpos_t-Datentyp, von dem ich glaube, dass er garantiert mindestens 64 Bit halten kann.

3

Haben Sie fseeko() mit den _FILE_OFFSET_BITS Präprozessorsymbol versuchten 64 zu gesetzt?

Dies wird Ihnen ein fseek() -artige Schnittstelle aber mit einem Offset-Parameter des Typs off_t statt lange. Einstellung _FILE_OFFSET_BITS = 64 macht off_t einen 64-Bit-Typ.Das gleiche gilt für ftello().

9

Wenn Sie ISO-C-Standardschnittstellen verwenden möchten, verwenden Sie fgetpos() und fsetpos(). Diese Funktionen sind jedoch nur nützlich, um eine Dateiposition zu speichern und später zur selben Position zurückzukehren. Sie repräsentieren die Position mit dem Typ fpos_t, der kein Integer-Datentyp sein muss. Zum Beispiel könnte es in einem datensatzbasierten System eine Struktur sein, die eine Datensatznummer und einen Offset innerhalb des Datensatzes enthält. Dies kann zu einschränkend sein.

POSIX definiert die Funktionen ftello() und fseeko(), die die Position mit dem Typ off_t darstellen. Dies muss ein Ganzzahl-Typ sein, und der Wert ist ein Byte-Offset vom Anfang der Datei. Sie können sie arithmetisch ausführen und fseeko() verwenden, um relative Suchvorgänge auszuführen. Dies funktioniert auf Linux und anderen POSIX-Systemen.

Zusätzlich kompilieren Sie mit -D_FILE_OFFSET_BITS=64 (Linux/Solaris). Dies definiert off_t als 64-Bit-Typ (d. H. off64_t) anstelle von long und definiert die Funktionen neu, die Dateioffsets als Versionen mit 64-Bit-Offsets verwenden. Dies ist der Standardwert, wenn Sie für 64-Bit kompilieren, also in diesem Fall nicht benötigt wird.

Verwandte Themen