Come si fa a determinare la dimensione di un file in C?
Domanda
Come posso capire la dimensione del file in byte?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Soluzione
Basato su NilObject codice:
#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;
}
Modifiche:
- Fatto il nome del file come argomento
const char
. - Corretto il
struct stat
definizione, a cui mancava il nome della variabile. - Restituisce
-1
in caso di errore invece di0
, che sarebbe ambiguo per un file vuoto.off_t
è un tipo signed quindi tutto questo è possibile.
Se vuoi fsize()
per stampare un messaggio di errore, è possibile utilizzare questo:
#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;
}
Su sistemi a 32 bit è necessario compilare questo con l'opzione -D_FILE_OFFSET_BITS=64
, altrimenti off_t
potrà contenere solo valori fino a 2 GB.Vedere "Utilizzo di LFS" sezione di Supporto File di grandi dimensioni in Linux per ulteriori dettagli.
Altri suggerimenti
Non utilizzare int
.File di oltre 2 gigabyte sono comuni, così come la sporcizia in questi giorni
Non utilizzare unsigned int
.I file superiori a 4 gb dimensioni sono comuni, così come un po ' -meno-comune di sporco
IIRC la libreria standard definisce off_t
come senza segno a 64 bit, che è ciò che tutti dovrebbero essere in uso.Siamo in grado di ridefinire essere di 128 bit in pochi anni, quando si iniziano ad avere i 16 exabyte in giro i file.
Se sei su windows, si dovrebbe utilizzare GetFileSizeEx - utilizza effettivamente firmato un numero intero a 64 bit, in modo che inizia a colpire problemi con 8 exabyte file.Sciocco Microsoft!:-)
Matt soluzione dovrebbe funzionare, tranne che è C++ invece di C, e l'iniziale raccontare non dovrebbe essere necessario.
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;
}
Fissa il tuo tutore per voi, troppo.;)
Aggiornamento:Questo non è davvero la soluzione migliore.È limitata a 4 gb di file in Windows, ed è probabile che più lento non solo utilizzando una piattaforma chiamata specifiche come GetFileSizeEx
o stat64
.
**Non fare questo (perché?):
Citando standard C99 doc che ho trovato online:"L'impostazione del file di indicatore di posizione di end-of-file, come con fseek(file, 0, SEEK_END), ha definito il comportamento di un flusso binario (a causa di possibili finali caratteri null) o per ogni flusso è stato dipendente di codifica che non è sicuramente la fine in iniziale stato di spostamento.**
Modificare la definizione di int in modo che i messaggi di errore possono essere trasmessi, e quindi utilizzare fseek() e ftell() per determinare la dimensione del file.
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
}
Se stai bene con l'utilizzo di std libreria c:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat filestat;
if (stat(file, &filestat) == 0) {
return filestat.st_size;
}
return 0;
}
POSIX
Il POSIX standard ha il suo proprio metodo per ottenere un file di dimensioni.
Includere il sys/stat.h
intestazione per utilizzare la funzione.
Sinossi
- Ottenere un file di statistiche di utilizzo
stat(3)
. - Ottenere i
st_size
proprietà.
Esempi
Nota:Esso limita la dimensione di 4GB
.Se non Fat32
filesystem quindi utilizzare la versione a 64bit!
#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)
Il ANSI C non fornisce direttamente il modo per determinare la lunghezza del file.
Dovremo usare la nostra mente.Per ora utilizzeremo la ricerca di un approccio!
Sinossi
Esempio
#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);
}
Se il file è
stdin
o un tubo. POSIX, ANSI C non funziona.
Sarà andando ritorno0
se il file è un tubo ostdin
.Parere:Si dovrebbe usare POSIX standard invece.Perché, ha il supporto a 64 bit.
E se si sta creando un'applicazione di Windows, utilizzare il GetFileSizeEx API come CRT file di I/O è disordinato, soprattutto per determinare la lunghezza del file, per la particolarità del file rappresentazioni su sistemi diversi ;)
Una rapida ricerca in Google un metodo che utilizza fseek e ftell e un thread con questa domanda con risposte che non può essere fatto solo in C in un altro modo.
Si potrebbe utilizzare una libreria di portabilità come NSPR (la biblioteca, che i poteri di Firefox) o di controllo la sua attuazione (piuttosto peloso).
Ho usato questo codice per trovare la lunghezza del file.
//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);
Provare questo --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Quello che fa è il primo, cercare al fine del file;quindi, report, in cui il puntatore del file è.Infine (questo è opzionale) si riavvolge all'inizio del file.Nota che fp
dovrebbe essere un flusso binario.
file_size contiene il numero di byte che contiene il file.Si noti che, poiché (secondo climits.h) il tipo unsigned long è limitato a 4294967295 byte (4 gb), avrete bisogno di trovare un diverso tipo di variabile se è probabile che a fare con file più grandi di quello.
Ecco un semplice e pulito, funzione che restituisce la dimensione del file.
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
}
Si sta andando ad avere bisogno di utilizzare una funzione di libreria per recuperare i dettagli di un file.Come C è completamente indipendente dalla piattaforma, si sta andando ad avere bisogno di farci sapere quale piattaforma / sistema operativo che si sta sviluppando per!
Guardando la questione, ftell
si può facilmente ottenere il numero di byte.
long size ;
size = ftell(FILENAME);
printf("total size is %ld bytes",size);
È possibile aprire il file, andare a 0 offset rispetto dal fondo del file con
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
il valore restituito da fseek è la dimensione del file.
Non ho un codice in C per un lungo periodo di tempo, ma penso che dovrebbe funzionare.