32-bit-Windows und die 2 GB Grenze für die Dateigröße (C mit fseek und ftell)
Ich bin versucht, port einen small-data-Analyse-Programm aus einer 64-bit-UNIX zu einem 32-bit-Windows-XP-system (nicht Fragen :)).
Aber nun habe ich Probleme mit der 2 GB Grenze für die Dateigröße (lange nicht 64 bit auf dieser Plattform).
Habe ich danach gesucht, dieser website und anderen für möglich sollutions aber finde keine, die direkt übersetzbar zu meinem problem.
Das problem ist in der Verwendung von fseek und ftell.
Kennt jemand eine änderung an den beiden folgenden Funktionen, um Sie arbeiten auf 32-bit-Windows XP für Dateien, die größer als 2 GB (eigentlich um 100GB).
Ist es wichtig, dass der Rückgabetyp von nsamples ist ein 64-bit-integer (möglicherweise int64_t).
long nsamples(char* filename)
{
FILE *fp;
long n;
/* Open file */
fp = fopen(filename, "rb");
/* Find end of file */
fseek(fp, 0L, SEEK_END);
/* Get number of samples */
n = ftell(fp) / sizeof(short);
/* Close file */
fclose(fp);
/* Return number of samples in file */
return n;
}
und
void readdata(char* filename, short* data, long start, int n)
{
FILE *fp;
/* Open file */
fp = fopen(filename, "rb");
/* Skip to correct position */
fseek(fp, start * sizeof(short), SEEK_SET);
/* Read data */
fread(data, sizeof(short), n, fp);
/* Close file */
fclose(fp);
}
Versuchte ich mit _fseeki64 und _ftelli64 mit den folgenden zu ersetzen nsamples:
__int64 nsamples(char* filename)
{
FILE *fp;
__int64 n;
int result;
/* Open file */
fp = fopen(filename, "rb");
if (fp == NULL)
{
perror("Error: could not open file!\n");
return -1;
}
/* Find end of file */
result = _fseeki64(fp, (__int64)0, SEEK_END);
if (result)
{
perror("Error: fseek failed!\n");
return result;
}
/* Get number of samples */
n = _ftelli64(fp) / sizeof(short);
printf("%I64d\n", n);
/* Close file */
fclose(fp);
/* Return number of samples in file */
return n;
}
für eine Datei 4815060992 bytes bekomme ich 260046848 Proben (z.B. _ftelli64
gibt 520093696 bytes) das ist seltsam.
Neugierig, wenn ich die (__int64)
cast in dem Aufruf von _fseeki64
bekomme ich einen Laufzeit-Fehler (ungültiges argument).
Irgendwelche Ideen?
Welchen compiler benutzt du? gcc? Visual (etwas)? Etwas anderes?
Ich bin mit MinGW ("kann nicht" VS da die Funktionen, die ich Schreibe, sind Teil eines f2py Python extension module). Die Win32-API könnte eine option sein, wenn es könnte leicht integriert werden in diese Funktion, ohne Zugabe zu viele Abhängigkeiten (wie Sie wahrscheinlich sagen, ich bin nicht so vertraut mit Windows :))
Ich habe eine speziellere Frage, wie auch, wenn, die wird beantwortet, werde ich die endgültige Lösung hier auch.
InformationsquelleAutor Pim Schellart | 2010-10-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es zwei Funktionen aufgerufen _fseeki64 und _ftelli64, die Unterstützung von mehr-Datei-offsets auch auf 32-bit-Windows:
Welchen compiler verwendest du? VisualStudio? Und welche version?
Ich benutze die neueste version von MinGW (im Grunde GCC-4.5). Als das Paket, ich bin kompilieren ist eine Python-Erweiterung mit f2py und ich habe keine Ahnung, wie das zu kompilieren, die mit VisualStudio.
Ich habe noch nie verwendet MinGW, so dass ich fürchte, ich kann nicht wirklich helfen. Aber haben Sie schaute auf ftello und fseeko die 64-bit-Versionen von ftell und fseek in Unix wie Bibliotheken?
Ich habe mir diese (fseeko _ftello) Funktionen, bin aber nicht sicher, ob Sie funktionieren auch auf Windows (auf meinem 64-bit-UNIX-Rechner ist es kein problem, da kann ich einfach fseek und ftell mit der 64 bit lang, es ist wirklich ein Windows-spezifisches Problem).
InformationsquelleAutor Codo
sorry für das posting früher, aber ich war beschäftigt mit anderen Projekten für eine Weile.
Die folgende Lösung funktioniert:
Der trick war die Verwendung
_open
stattfopen
um die Datei zu öffnen.Ich verstehe immer noch nicht genau, warum das gemacht werden muss, aber zumindest das funktioniert jetzt.
Vielen Dank an alle für Ihre Vorschläge, die schließlich wies mich in die richtige Richtung.
InformationsquelleAutor Pim Schellart
Mein BC sagt:
Ich vermute, dass Ihre print-routine ist 32-bit. Ihre offset zurückgegeben, ist wahrscheinlich richtig, aber abgehackt irgendwo.
InformationsquelleAutor dascandy
Und für den gcc finden, SO Frage Eine Million fünf und dreißig tausend sechs hundert sieben und fünfzig. Wo ist die Beratung kompilieren mit der Option-D_FILE_OFFSET_BITS=64, so dass die versteckte variable(N) (Typ off_t) von der f-Bewegung-rund Funktionen ist(sind) 64-bit.
Für MinGW: "Large-file support (LFS) wurde umgesetzt durch die Neudefinition der stat und seek-Funktionen und-Typen auf Ihrem 64-bit-äquivalente. Für fseek und ftell, separate LFS-Versionen, fseeko und ftello, basierend auf fsetpos und fgetpos, sind in LibGw32C." (Referenz). In neueren Versionen von gcc, fseeko und ftello sind eingebaut und in eine separate Bibliothek ist nicht erforderlich.
Schellart: ich kann weder bestätigen noch leugnen. Meine beiden derzeit arbeiten gcc-setups sind Linux/POSIX (im Zusammenhang mit Ihrer Frage). Testen auf die, ich sehe LFS Verhalten von fseek() und ftell(). Also ich bin nicht in der Lage zu testen, mit dem gcc in einem nicht-POSIX-Umgebung.
fseeko und ftello sind mit der neuesten MinGW gcc 4.8.2; Sie brauchen nicht LibGw32C.
InformationsquelleAutor Eric Towers