Détermination de la taille d'un fichier de plus de 4 Go
Question
Le code le fait actuellement et fgetpos gère les fichiers de plus de 4 Go, mais la recherche renvoie une erreur. Toute idée de recherche de la fin d'un fichier > 4 Go
?
fpos_t currentpos;
sok=fseek(fp,0,SEEK_END);
assert(sok==0,"Seek error!");
fgetpos(fp,¤tpos);
m_filesize=currentpos;
La solution
Si vous utilisez Windows, vous souhaitez GetFileSizeEx ( MSDN) . La valeur de retour est un entier de 64 bits.
Sous linux, la stat64 (page de manuel) est correcte. fstat si vous travaillez avec un FILE *.
Autres conseils
Ignorez toutes les réponses avec " 64 " apparaissant en eux. Sous Linux, vous devez ajouter -D_FILE_OFFSET_BITS = 64
à votre CFLAGS et utiliser les fonctions fseeko
et ftello
qui prennent / retournent off_t
valeurs au lieu de long
. Celles-ci ne font pas partie de C mais de POSIX. D'autres systèmes POSIX (non Linux) peuvent avoir besoin d'options différentes pour s'assurer que off_t
est 64 bits; consultez votre documentation.
Ce code fonctionne pour moi sous Linux:
int64_t bigFileSize(const char *path)
{
struct stat64 S;
if(-1 == stat64(path, &S))
{
printf("Error!\r\n");
return -1;
}
return S.st_size;
}
(volé dans le manuel de la glibc)
int fgetpos64 (flux FILE *, position fpos64_t *)
Cette fonction est similaire à fgetpos mais la position du fichier est renvoyée dans une variable de type fpos64_t
sur laquelle les points de position sont placés.
Si les sources sont compilées avec _FILE_OFFSET_BITS == 64
sur une machine 32 bits, cette fonction est disponible sous le nom fgetpos
et remplace de manière transparente l'ancienne interface.
Stat est toujours mieux que fseek pour déterminer la taille du fichier, il échouera en toute sécurité sur des éléments qui ne sont pas un fichier. La taille de fichier 64 bits est une opération spécifique, sur gcc vous pouvez mettre " 64 " à la fin des commandes, ou vous pouvez le forcer à faire tous les appels standard 64 par défaut. Consultez le manuel de votre compilateur pour plus de détails.
Sous Linux, vous pourriez au moins utiliser lseek64 au lieu de fseek.