Frage

Wie kann ich die Größe einer Datei in Bytes ermitteln?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
War es hilfreich?

Lösung

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:

  • Das Dateinamenargument wurde zu a gemacht const char.
  • Korrigiert struct stat Definition, bei der der Variablenname fehlte.
  • Kehrt zurück -1 auf Fehler statt 0, was für eine leere Datei mehrdeutig wäre. off_t ist ein signierter Typ, daher ist dies möglich.

Falls Sie es wollen fsize() Um bei einem Fehler eine Meldung auszudrucken, 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, ansonsten off_t speichert nur Werte bis zu 2 GB.Weitere Informationen finden Sie im Abschnitt „Verwenden von LFS“. Unterstützung großer Dateien unter Linux für Details.

Andere Tipps

Nicht verwenden int.Dateien mit einer Größe von mehr als 2 Gigabyte gelten heutzutage als Schmutz

Nicht verwenden unsigned int.Dateien mit einer Größe von mehr als 4 Gigabyte kommen häufig vor, etwas seltener kommt Schmutz vor

IIRC definiert die Standardbibliothek off_t als vorzeichenlose 64-Bit-Ganzzahl, die jeder verwenden sollte.Wir können das in ein paar Jahren auf 128 Bit umdefinieren, wenn wir anfangen, 16-Exabyte-Dateien herumzuhängen.

Wenn Sie Windows verwenden, sollten Sie verwenden GetFileSizeEx - 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++ statt C ist und der 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;
}

Ich habe auch Ihre Zahnspange für Sie repariert.;)

Aktualisieren:Das ist nicht wirklich die beste Lösung.Es ist auf 4 GB-Dateien unter Windows beschränkt und wahrscheinlich langsamer als nur die Verwendung eines plattformspezifischen Aufrufs wie z GetFileSizeEx oder stat64.

**Tu das nicht (Warum?):

Ich zitiere das C99-Standarddokument, das ich online gefunden habe:„Das Setzen des Dateipositionsindikators auf das Dateiende, wie bei fseek(file, 0, SEEK_END), hat ein undefiniertes Verhalten für einen Binärstream (aufgrund möglicher nachgestellter Nullzeichen) oder für jeden Stream mit zustandsabhängiger Codierung, der dies tut nicht unbedingt im ursprünglichen Schaltzustand enden.**

Ändern Sie die Definition in int, damit Fehlermeldungen übertragen werden können, und ermitteln Sie dann mit fseek() und ftell() die Dateigröße.

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
}

Wenn Sie mit der Verwendung der Standard-C-Bibliothek zufrieden sind:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

POSIX

Der POSIX Der Standard verfügt über eine eigene Methode zum Ermitteln der Dateigröße.
Umfassen die sys/stat.h Header, um die Funktion zu verwenden.

Zusammenfassung

  • Dateistatistiken abrufen mit stat(3).
  • Erhalten Sie die st_size Eigentum.

Beispiele

Notiz:Es begrenzt die Größe auf 4GB.Wenn nicht Fat32 Dateisystem, dann verwenden Sie die 64bit-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);
}

ANSI C (Standard)

Der ANSI C bietet keine direkte Möglichkeit, die Länge der Datei zu bestimmen.
Wir müssen unseren Verstand einsetzen.Im Moment verwenden wir den Suchansatz!

Zusammenfassung

  • Suchen Sie die Datei bis zum Ende mit fseek(3).
  • Ermitteln Sie die aktuelle Position mit ftell(3).

Beispiel

#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 ist stdin oder eine Pfeife. POSIX, ANSI C wird nicht funktionieren.
Es wird wiederkommen 0 wenn die Datei eine Pipe ist oder stdin.

Meinung:Du solltest benutzen POSIX stattdessen Standard.Weil es 64-Bit-Unterstützung bietet.

Und wenn Sie eine Windows-App erstellen, verwenden Sie die GetFileSizeEx API als CRT-Datei-E/A ist chaotisch, insbesondere bei der Bestimmung der Dateilänge, aufgrund von Besonderheiten bei der Dateidarstellung auf verschiedenen Systemen ;)

Eine schnelle Suche in Google hat gefunden eine Methode, die fseek und ftell verwendet und ein Thread mit dieser Frage mit Antworten, dass es auf andere Weise nicht nur in C möglich ist.

Sie könnten eine Portabilitätsbibliothek wie verwenden NSPR (die Bibliothek, die Firefox antreibt) oder überprüfen seine Umsetzung (ziemlich haarig).

Ich habe diesen Codesatz 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);

Dies bewirkt zunächst, dass bis zum Ende der Datei gesucht wird.Geben Sie dann an, wo sich der Dateizeiger befindet.Zum Schluss (dies ist optional) wird zum Anfang der Datei zurückgespult.Beachten Sie, dass fp sollte ein binärer Stream sein.

file_size enthält die Anzahl der Bytes, die die Datei enthält.Beachten Sie, dass (laut climits.h) der unsigned long-Typ auf 4294967295 Bytes (4 Gigabyte) beschränkt ist. Sie müssen einen anderen Variablentyp finden, wenn Sie wahrscheinlich mit Dateien arbeiten, die größer sind.

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 müssen eine Bibliotheksfunktion verwenden, um die Details einer Datei abzurufen.Da C völlig plattformunabhängig ist, müssen Sie uns mitteilen, für welche Plattform/welches Betriebssystem Sie entwickeln!

Betrachtet man die Frage, ftell kann leicht die Anzahl der Bytes ermitteln.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

Sie können die Datei öffnen und mit dem Offset relativ zum unteren Rand der Datei auf 0 gehen

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

Der von fseek zurückgegebene Wert ist die Größe der Datei.

Ich habe lange nicht in C programmiert, aber ich denke, es sollte funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top