Comment puis-je déterminer la taille d'un fichier, en octets?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
, pourquoi pas FILE* file
? -1
Comment puis-je déterminer la taille d'un fichier, en octets?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
, pourquoi pas FILE* file
? -1
Réponses:
Basé sur le code de 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;
}
Changements:
const char
.struct stat
définition, qui manquait le nom de la variable.-1
sur erreur au lieu de 0
, ce qui serait ambigu pour un fichier vide. off_t
est un type signé, c'est donc possible.Si vous souhaitez fsize()
imprimer un message d'erreur, vous pouvez utiliser ceci:
#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;
}
Sur les systèmes 32 bits, vous devez le compiler avec l'option -D_FILE_OFFSET_BITS=64
, sinon off_t
ne contiendra que des valeurs jusqu'à 2 Go. Consultez la section «Utilisation de LFS» de la prise en charge des fichiers volumineux sous Linux pour plus de détails.
fseek
+ ftell
comme proposé par Derek.
fseek
+ ftell
comme proposé par Derek. Non . La norme C précise que fseek()
pour SEEK_END
un fichier binaire est un comportement non défini. 7.19.9.2 La fseek
fonction ... Un flux binaire n'a pas besoin de prendre en charge de manière significative les fseek
appels avec une valeur SEEK_END
whence de , et comme indiqué ci-dessous, qui provient de la note 234 à la p. 267 de la norme lié par C, et qui en particulier des étiquettes fseek
pour SEEK_END
un flux binaire en tant que comportement non défini. .
N'utilisez pas int
. Les fichiers de plus de 2 gigaoctets sont courants comme de la saleté de nos jours
N'utilisez pas unsigned int
. Les fichiers de plus de 4 gigaoctets sont courants en tant que saleté légèrement moins courante
IIRC, la bibliothèque standard définit off_t
comme un entier 64 bits non signé, ce que tout le monde devrait utiliser. Nous pouvons redéfinir cela à 128 bits dans quelques années lorsque nous commencerons à avoir 16 fichiers exaoctets qui traînent.
Si vous êtes sous Windows, vous devez utiliser GetFileSizeEx - il utilise en fait un entier 64 bits signé, de sorte qu'ils commenceront à rencontrer des problèmes avec 8 fichiers exaoctets. Microsoft stupide! :-)
La solution de Matt devrait fonctionner, sauf que c'est C ++ au lieu de C, et le tell initial ne devrait pas être nécessaire.
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;
}
Correction de votre attelle pour vous aussi. ;)
Mise à jour: ce n'est pas vraiment la meilleure solution. Il est limité à 4 Go de fichiers sur Windows et il est probablement plus lent que d'utiliser simplement un appel spécifique à la plate-forme comme GetFileSizeEx
ou stat64
.
long int
de ftell()
. (unsigned long)
la coulée n'améliore pas la portée car déjà limitée par la fonction. ftell()
retourne -1 en cas d'erreur et qui est obscurcie avec la distribution. Suggérer de fsize()
renvoyer le même type que ftell()
.
** Ne faites pas ça ( pourquoi? ):
Citant le document standard C99 que j'ai trouvé en ligne: «La définition de l'indicateur de position du fichier sur la fin du fichier, comme avec
fseek(file, 0, SEEK_END)
, a un comportement indéfini pour un flux binaire (en raison de possibles caractères nulles de fin) ou pour tout flux avec un codage dépendant de l'état qui ne se termine pas assurément dans l'état de décalage initial. **
Modifiez la définition en int afin que les messages d'erreur puissent être transmis, puis utilisez fseek()
et ftell()
pour déterminer la taille du fichier.
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
et ftello
(ou fseek
et ftell
si vous êtes bloqué sans l'ancien et satisfait des limites de taille de fichier avec lesquelles vous pouvez travailler) sont la bonne façon de déterminer la longueur d'un fichier. stat
Les solutions basées sur les fichiers ne fonctionnent pas sur de nombreux "fichiers" (tels que les périphériques de bloc) et ne sont pas portables sur des systèmes non POSIX.
Le standard POSIX a sa propre méthode pour obtenir la taille du fichier.
Incluez l'en- sys/stat.h
tête pour utiliser la fonction.
stat(3)
.st_size
propriété.Remarque : il limite la taille à 4GB
. Si ce n'est pas le Fat32
système de fichiers, utilisez la version 64 bits!
#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);
}
L' ANSI C ne fournit pas directement le moyen de déterminer la longueur du fichier.
Nous devrons utiliser notre esprit. Pour l'instant, nous allons utiliser l'approche de recherche!
fseek(3)
.ftell(3)
.#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);
}
Si le fichier est
stdin
ou un tube. POSIX, ANSI C ne fonctionnera pas.
Il retournera0
si le fichier est un tube oustdin
.Opinion : Vous devriez utiliser le standard POSIX à la place. Parce qu'il prend en charge 64 bits.
struct _stat64
et __stat64()
pour _Windows.
Et si vous créez une application Windows, utilisez l' API GetFileSizeEx car les E / S de fichier CRT sont compliquées , en particulier pour déterminer la longueur de fichier, en raison des particularités des représentations de fichiers sur différents systèmes;)
Si vous êtes d'accord avec l'utilisation de la bibliothèque std c:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat filestat;
if (stat(file, &filestat) == 0) {
return filestat.st_size;
}
return 0;
}
Une recherche rapide dans Google a trouvé une méthode utilisant fseek et ftell et un fil avec cette question avec des réponses que cela ne peut pas être fait en C d'une autre manière.
Vous pouvez utiliser une bibliothèque de portabilité comme NSPR (la bibliothèque qui alimente Firefox) ou vérifier son implémentation (plutôt poilue).
J'ai utilisé cet ensemble de code pour trouver la longueur du fichier.
//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);
Essaye ça --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Ce que cela fait, c'est d'abord chercher la fin du fichier; puis, indiquez où se trouve le pointeur de fichier. Enfin (c'est facultatif), il revient au début du fichier. Notez que cela fp
devrait être un flux binaire.
file_size contient le nombre d'octets que contient le fichier. Notez que puisque (selon climits.h) le type long non signé est limité à 4294967295 octets (4 gigaoctets), vous devrez trouver un type de variable différent si vous êtes susceptible de traiter des fichiers plus volumineux que cela.
ftell
il ne renvoie pas de valeur représentative du nombre d'octets pouvant être lus à partir du fichier.
J'ai une fonction qui fonctionne bien uniquement avec stdio.h
. Je l'aime beaucoup et cela fonctionne très bien et est assez concis:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
Voici une fonction simple et propre qui renvoie la taille du fichier.
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
}
Vous pouvez ouvrir le fichier, aller à 0 offset relatif à partir du bas du fichier avec
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
la valeur renvoyée par fseek est la taille du fichier.
Je n'ai pas codé en C pendant longtemps, mais je pense que cela devrait fonctionner.
En regardant la question, ftell
peut facilement obtenir le nombre d'octets.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftell
attend un descripteur de fichier, pas un nom de fichier, comme argument.
ftell
n'attend pas de descripteur de fichier, il en attend un à la FILE*
place. Consultez d'abord la page de manuel!
fseek()
abord utiliser pour rechercher la fin du fichier, et aussi, ftell()
attend une FILE *
, pas une chaîne! Vous seriez bien servi pour étoffer votre réponse.