Wie kann ich die Größe einer Datei in Bytes ermitteln?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file, warum nicht FILE* file? -1
Wie kann ich die Größe einer Datei in Bytes ermitteln?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file, warum nicht FILE* file? -1
Antworten:
Basierend auf dem Code von NilObject:
#include <sys/stat.h>
#include <sys/types.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}
Änderungen:
const char.struct statDefinition wurde korrigiert , bei der der Variablenname fehlte.-1bei Fehler statt zurück 0, was für eine leere Datei nicht eindeutig wäre. off_tist ein signierter Typ, daher ist dies möglich.Wenn Sie fsize()eine Fehlermeldung drucken möchten , können Sie Folgendes verwenden:
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
fprintf(stderr, "Cannot determine size of %s: %s\n",
filename, strerror(errno));
return -1;
}
Auf 32-Bit-Systemen sollten Sie dies mit der Option kompilieren -D_FILE_OFFSET_BITS=64, da sonst off_tnur Werte bis zu 2 GB gespeichert werden. Weitere Informationen finden Sie im Abschnitt "Verwenden von LFS" der Unterstützung großer Dateien unter Linux .
fseek+, ftellwie von Derek vorgeschlagen.
fseek+, ftellwie von Derek vorgeschlagen. Nein. Der C-Standard besagt ausdrücklich, dass fseek()to SEEK_ENDin einer Binärdatei ein undefiniertes Verhalten ist. 7.19.9.2 Die fseekFunktion ... Ein binärer Stream muss fseekAufrufe mit einem Woher-Wert vonSEEK_END und, wie unten angegeben, aus Fußnote 234 auf S. 22 nicht sinnvoll unterstützen . 267 des C - Standard verbunden ist , und welche spezifisch Etiketten fseekzu SEEK_ENDin einem Binärstrom als undefiniertes Verhalten. .
Nicht benutzen int . Dateien mit einer Größe von mehr als 2 Gigabyte sind heutzutage als Schmutz üblich
Nicht benutzen unsigned int . Dateien mit einer Größe von mehr als 4 Gigabyte sind häufig als etwas weniger häufig vorkommender Schmutz
IIRC Die Standardbibliothek definiert off_tals vorzeichenlose 64-Bit-Ganzzahl, die jeder verwenden sollte. Wir können das in ein paar Jahren auf 128 Bit neu definieren, wenn 16 Exabyte-Dateien herumhängen.
Wenn Sie unter Windows arbeiten, sollten Sie GetFileSizeEx verwenden - es wird tatsächlich eine vorzeichenbehaftete 64-Bit-Ganzzahl verwendet, sodass Probleme mit 8 Exabyte-Dateien auftreten. Dummes Microsoft! :-)
Matts Lösung sollte funktionieren, außer dass es C ++ anstelle von C ist und das anfängliche Tell nicht notwendig sein sollte.
unsigned long fsize(char* file)
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
unsigned long len = (unsigned long)ftell(f);
fclose(f);
return len;
}
Reparierte auch deine Zahnspange für dich. ;)
Update: Dies ist nicht wirklich die beste Lösung. Es ist auf 4 GB-Dateien unter Windows beschränkt und wahrscheinlich langsamer als nur ein plattformspezifischer Aufruf wie GetFileSizeExoder stat64.
long intvon zurück ftell(). (unsigned long)Das Gießen verbessert die Reichweite nicht, da sie bereits durch die Funktion begrenzt ist. ftell()Rückgabe -1 bei Fehler und das wird mit der Besetzung verschleiert. Schlagen Sie vor fsize(), den gleichen Typ wie zurückzugeben ftell().
** Tu das nicht ( warum? ):
Zitieren des C99-Standarddokuments, das ich online gefunden habe: "Das Setzen des Dateipositionsindikators auf Dateiende hat wie bei ein
fseek(file, 0, SEEK_END)undefiniertes Verhalten für einen Binärdatenstrom (aufgrund möglicher nachfolgender Nullzeichen) oder für jeden Datenstrom mit zustandsabhängiger Codierung das endet nicht sicher im anfänglichen Schaltzustand. **
Ändern Sie die Definition in int, damit Fehlermeldungen übertragen werden können, und verwenden Sie dann fseek()und ftell(), um die Dateigröße zu bestimmen.
int fsize(char* file) {
int size;
FILE* fh;
fh = fopen(file, "rb"); //binary mode
if(fh != NULL){
if( fseek(fh, 0, SEEK_END) ){
fclose(fh);
return -1;
}
size = ftell(fh);
fclose(fh);
return size;
}
return -1; //error
}
fseekound ftello(oder fseekund ftellwenn Sie nicht weiterkommen , ohne die ehemaligen und glücklich mit Grenzen für die Dateigrößen können Sie mit der Arbeit) sind der richtige Weg , um die Länge einer Datei zu bestimmen. stat-basierte Lösungen funktionieren nicht auf vielen "Dateien" (z. B. Blockgeräten) und sind nicht auf nicht POSIX-ähnliche Systeme portierbar.
Der POSIX- Standard verfügt über eine eigene Methode zum Abrufen der Dateigröße.
Fügen Sie den sys/stat.hHeader ein, um die Funktion zu verwenden.
stat(3).st_sizeEigenschaft.Hinweis : Die Größe wird auf begrenzt 4GB. Wenn nicht Fat32Dateisystem, dann verwenden Sie die 64-Bit-Version!
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat info;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat64 info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
Das ANSI C bietet nicht direkt die Möglichkeit, die Länge der Datei zu bestimmen.
Wir müssen unseren Verstand benutzen. Im Moment verwenden wir den Suchansatz!
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* fp = fopen(argv[1]);
int f_size;
fseek(fp, 0, SEEK_END);
f_size = ftell(fp);
rewind(fp); // to back to start again
printf("%s: size=%ld", (unsigned long)f_size);
}
Wenn die Datei
stdinoder eine Pipe ist. POSIX, ANSI C funktioniert nicht.
Es wird zurückgegeben,0wenn die Datei eine Pipe ist oderstdin.Meinung : Sie sollten stattdessen den POSIX- Standard verwenden. Weil es 64-Bit-Unterstützung hat.
struct _stat64und __stat64()für _Windows.
Und wenn Sie eine Windows-App erstellen , verwenden Sie die GetFileSizeEx- API, da die CRT-Datei-E / A aufgrund von Besonderheiten bei der Dateidarstellung auf verschiedenen Systemen unübersichtlich ist, insbesondere zum Bestimmen der Dateilänge.
Wenn Sie mit der Verwendung der Standard-C-Bibliothek einverstanden sind:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat filestat;
if (stat(file, &filestat) == 0) {
return filestat.st_size;
}
return 0;
}
Bei einer schnellen Suche in Google wurde eine Methode mit fseek und ftell gefunden sowie einen Thread mit dieser Frage mit Antworten, die auf andere Weise nicht nur in C ausgeführt werden können.
Sie können eine Portabilitätsbibliothek wie NSPR (die Bibliothek, die Firefox unterstützt) verwenden oder deren Implementierung überprüfen (ziemlich haarig).
Ich habe diesen Code verwendet, um die Dateilänge zu ermitteln.
//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");
//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);
//stores file size
long file_length = buffer.st_size;
fclose(i_file);
Versuche dies --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Suchen Sie zunächst bis zum Ende der Datei. Geben Sie dann an, wo sich der Dateizeiger befindet. Zuletzt (dies ist optional) wird zum Anfang der Datei zurückgespult. Beachten Sie, dassfp dies ein binärer Stream sein sollte.
file_size enthält die Anzahl der Bytes, die die Datei enthält. Da der vorzeichenlose lange Typ (laut klimits.h) auf 4294967295 Byte (4 Gigabyte) begrenzt ist, müssen Sie einen anderen Variablentyp finden, wenn Sie wahrscheinlich mit größeren Dateien arbeiten.
ftellwird kein Wert zurückgegeben, der für die Anzahl der Bytes repräsentativ ist, die aus der Datei gelesen werden können.
Ich habe eine Funktion, die nur gut funktioniert stdio.h. Ich mag es sehr und es funktioniert sehr gut und ist ziemlich prägnant:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
Hier ist eine einfache und saubere Funktion, die die Dateigröße zurückgibt.
long get_file_size(char *path)
{
FILE *fp;
long size = -1;
/* Open file for reading */
fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fp.close();
return
}
Sie können die Datei öffnen und mit dem Versatz 0 vom unteren Rand der Datei auf 0 gehen
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
Der von fseek zurückgegebene Wert entspricht der Größe der Datei.
Ich habe lange nicht in C codiert, aber ich denke, es sollte funktionieren.
Wenn Sie sich die Frage ansehen, ftellkönnen Sie leicht die Anzahl der Bytes ermitteln.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftellerwartet als Argument einen Dateideskriptor, keinen Dateinamen.
ftellerwartet keinen Dateideskriptor, sondern einen FILE*. Siehe zuerst die Manpage!
fseek()zuerst das Ende der Datei suchen müssen und außerdem eine Zeichenfolge ftell()erwarten FILE *, keine Zeichenfolge! Es wäre gut, wenn Sie Ihre Antwort konkretisieren würden.