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 stat
Definition wurde korrigiert , bei der der Variablenname fehlte.-1
bei Fehler statt zurück 0
, was für eine leere Datei nicht eindeutig wäre. off_t
ist 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_t
nur 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
+, ftell
wie von Derek vorgeschlagen.
fseek
+, ftell
wie von Derek vorgeschlagen. Nein. Der C-Standard besagt ausdrücklich, dass fseek()
to SEEK_END
in einer Binärdatei ein undefiniertes Verhalten ist. 7.19.9.2 Die fseek
Funktion ... Ein binärer Stream muss fseek
Aufrufe 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 fseek
zu SEEK_END
in 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_t
als 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 GetFileSizeEx
oder stat64
.
long int
von 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
}
fseeko
und ftello
(oder fseek
und ftell
wenn 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.h
Header ein, um die Funktion zu verwenden.
stat(3)
.st_size
Eigenschaft.Hinweis : Die Größe wird auf begrenzt 4GB
. Wenn nicht Fat32
Dateisystem, 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
stdin
oder eine Pipe ist. POSIX, ANSI C funktioniert nicht.
Es wird zurückgegeben,0
wenn die Datei eine Pipe ist oderstdin
.Meinung : Sie sollten stattdessen den POSIX- Standard verwenden. Weil es 64-Bit-Unterstützung hat.
struct _stat64
und __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.
ftell
wird 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, ftell
können Sie leicht die Anzahl der Bytes ermitteln.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftell
erwartet als Argument einen Dateideskriptor, keinen Dateinamen.
ftell
erwartet 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.