IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Calculer la taille d'un fichier


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 48
    Par défaut Calculer la taille d'un fichier
    Bonjour

    Je cherche à connaitre la taille de certains fichiers en octets.

    Voici les 2 méthodes que j'ai tentée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
     
    int main(int argc, char *argv[] )
    {
        struct stat buf;
        int result;
        long size;
        FILE *fd;
        result = stat ( argv[1], &buf );
        if (result == -1 ) return (-1);
        fprintf(stdout, "1)Taille de '%s' : %ld octets\n", argv[1], (long )buf.st_size);
        if (( fd = fopen (argv[1], "rb")) == NULL)
        {perror("\t fopen() ");return (-1); }
        fseek(fd, 0, SEEK_END);
        size = ftell(fd);
        fclose (fd);
        fprintf(stdout, "2)Taille de '%s' : %ld octets\n", argv[1], size);
        return 0;
    }
    Ces 2 méthodes marche trés bien sur des fichiers de plusieurs Mo mais qand je fait le test sur un fichier de plusieurs Go ca ne marche pas.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    $ ./test /mnt/data/LiveCD.iso  // Taille réelle 735715328 octets
    1)Taille de '/mnt/data/LiveCD.iso'  : 735715328 octets
    2)Taille de '/mnt/data/LiveCD.iso'  : 735715328 octet
    $ ./test /mnt/data/LiveDVD.iso  // Taille réelle 4681426944 octets
    1)Taille de '/mnt/data/LiveDVD.iso' : 386459648 octets
    2)Taille de '/mnt/data/LiveDVD.iso' : 386459648 octets

    J'ai consulté la FAQ qui parle de la secondes méthodes.
    Bref je suis coincé.

    Si vous avez des idées pour moi, j'en serais ravie

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    pour les "gros" fichiers, mieux vaut utiliser ftello() et fseeko() en lieu et place de ftell() et fseek().
    C'est un simple problème de dépassement de capacité sur les entiers codés sur 32 bits.

    cf man page : http://man.developpez.com/man3/ftello.3.php

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Pourquoi faire compliqué quand on peut faire simple ?????????

    Il y a une fonction toute faite.....


    http://www.scit.wlv.ac.uk/~jphb/spos...alls/stat.html


    (ça fait bizarre.. 2 fois en 2 jours que je le met, ce lien... )

    Dans les champs, il y en a un qui s'apelle

    st_size File size in bytes
    Un include, une déclaration, une ouverture de fichier, un appel, fermeture du fichier, et hop le tour est joué...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 48
    Par défaut
    Je viens de tester avec les fonctions que tu me conseil mais cela ne semble pas changer grand chose. Cela me donne les mêmes résultats qu'avec stat(), ftell(), fseek() ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
     
    int main(int argc, char *argv[] )
    {
        FILE *fd;
        off_t size;
        if (( fd = fopen (argv[1], "rb")) == NULL)
        {perror("\t fopen() ");return (-1); }
        fseeko(fd, 0, SEEK_END);
        size = ftello(fd);
        fclose (fd);
        fprintf(stdout, "2)Taille de '%s' : %ld octets\n", argv[1], (long )size);
        return 0;
    }
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $ ./test /mnt/data/LiveDVD.iso  // Taille réelle 4681426944 octets
    2)Taille de '/mnt/data/LiveDVD.iso' : 386459648 octets

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 48
    Par défaut
    Citation Envoyé par souviron34
    Pourquoi faire compliqué quand on peut faire simple ?????????
    Il y a une fonction toute faite.....
    http://www.scit.wlv.ac.uk/~jphb/spos...alls/stat.html

    C'est la première fonction que j'ai utilisé cf mon premier post.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    à ce compte-là Neitsa t'a donné la réponse....

    Et si tu dépasses toutes les capacités, alors il te faut soit le lire à la main, soit faire une recherche par dichotomie en stockant le résultat dans un double par exemple, en faisant des fseek/ftell...

  7. #7
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Le problème vient souvent de la définition du type off_t (offset type) qui est défini en tant qu'entier 32 bits.

    Comme le faisait remarquer Souviron34, la fonction stat() devrait faire l'affaire. Le problème reste le membre st_size si c'est un type "offset type" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct stat {
     
        [...] 
        off_t         st_size;     /* Taille totale en octets     */
        [...]
     
    };
    Doc, même en utilisant ftello(), fseeko() ou stat() on se retrouve confronter à ce problème.

    Un simple define permet de passer off_t en 64bits :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define _FILE_OFFSET_BITS 64
    Par contre j'ignore si c'est généralisé ou si c'est le même #define partout suivant les implémentations. A voir donc, faut fouiller les fichiers d'en-tête...

    P.S : sinon y'a aussi la fonction stat64()... Bref avec toutes ces fonctions, y'en a bien une qui devrait fonctionner !

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    et d'ailleurs je viens de penser, si jamais on dépasse la capacité de off_t, il y a toujours les variables blk_size et nb de blocks, qui elles devraient être correctes.

    Là ensuite, il n'y a plus qu'à faire la multiplication à la main...

    [EDIT]

    Et sinon une bonne vieille boucle fgetc

    [/EDIT]

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 sur la ligne de compilation. Et comme alors off_t fait 64 bits, il faut faire attention a ne pas le tronquer ou a ne pas le passer a une fonction variadique (comme printf) qui s'attend a autre chose (long ne fait pas d'office 64 bits par exemple meme si off_t le fait)

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    116
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2007
    Messages : 116
    Par défaut
    petit détail mais si tu veux que ca marche aussi pour les liens utilises lstat :-)

Discussions similaires

  1. Calculer la tailles moyennes des fichiers
    Par hacbao dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 22/12/2013, 23h01
  2. Réponses: 1
    Dernier message: 30/10/2008, 10h52
  3. Calculer la taille d'un fichier
    Par emil_2 dans le forum Qt
    Réponses: 2
    Dernier message: 24/04/2008, 16h04
  4. calculer la taille réellement occupée par un fichier
    Par d_idaho dans le forum VBScript
    Réponses: 1
    Dernier message: 05/03/2007, 15h14
  5. Réponses: 9
    Dernier message: 26/08/2006, 19h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo