2010-08-18 8 views
8

J'essaie de comprendre comment utiliser stat() pour capturer des informations sur un fichier. Ce dont j'ai besoin, c'est d'être capable d'imprimer plusieurs champs d'information sur un fichier. Donc ..Utilisation de Struct Stat()

#include <iostream> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
using namespace std; 

int main() { 
    struct stat buf; 
    stat("file",&buf); 
       ... 
    cout << st_dev << endl; 
    cout << st_ino << endl; 
    cout << st_mode << endl; 
    cout << st_nlink << endl; 
    cout << st_uid << endl; 
    cout << st_gid << endl; 
    cout << st_rdev << endl; 
    cout << st_size << endl; 
    cout << st_blksize << endl; 
    cout << st_blocks << endl; 
    cout << st_atime << endl; 
    cout << st_mtime << endl; 
    cout << st_ctime << endl; 
    ... 
} 

Je suis complètement confus sur la façon de faire cela. Pourquoi & buf un paramètre à stat? Je ne me soucie pas de stocker ces informations en mémoire, j'ai juste besoin des champs outputted dans mon programme C++. Comment accéder aux informations contenues dans la structure? Est-ce que buf est censé contenir les informations retournées par stat()?

+0

Je vois, pour tous thankyou les réponses. Ils étaient très utiles. Est-ce que quelqu'un sait comment utiliser stdin, stdout ou stderr comme paramètres pour stat fonctionne? Ce sont des flux et non des fichiers, alors comment stat peut-il remplir une structure avec des données? –

+0

Utilisez 'fstat', qui prend un descripteur de fichier comme premier argument au lieu d'un chemin. –

+0

Normalement je le ferais mais l'environnement est quelque peu artificiel car c'est la partie OS d'un simulateur d'architecture que j'ai écrit. Donc, quand un fichier est ouvert par un syscall, j'ai mon propre vecteur pour agir comme une table de descripteur de fichier. Est-il un bon moyen de capturer le descripteur de fichier réel sur la machine pour un fichier tel qu'il est ouvert? Si c'était le cas, j'utiliserais fstat car aucune traduction ne serait nécessaire entre les statistiques de flux et les statistiques de fichier. –

Répondre

11

Oui, buf est utilisé ici en tant que paramètre externe. Les résultats sont stockés dans buf et la valeur de retour stat est un code d'erreur indiquant si l'opération stat a réussi ou échoué.

Ceci est fait de cette manière car stat est une fonction POSIX, conçue pour C, qui ne supporte pas les mécanismes de signalisation d'erreur hors bande comme les exceptions. Si stata renvoyé une structure, alors il n'aurait aucun moyen d'indiquer des erreurs. L'utilisation de cette méthode de paramétrage externe permet également à l'appelant de choisir où stocker les résultats, mais c'est une caractéristique secondaire. Il est parfaitement possible de transmettre l'adresse d'une variable locale normale, comme vous l'avez fait ici.

Vous accédez aux champs d'une structure comme vous le feriez pour n'importe quel autre objet. Je présume que vous êtes au moins familier avec la notation d'objet? Par exemple. le champ st_dev au sein de la structure stat appelée buf est accessible par buf.st_dev. Alors:

cout << buf.st_dev << endl; 

etc.

2

Vous avez plusieurs erreurs dans votre code:

  • Vous avez besoin &buf, avec un seul 'f'.
  • Vous devez dire par ex. buf.st_dev lors de l'impression, car st_dev est un champ dans la variable struct.

Depuis buf est une variable locale sur la pile, vous n'êtes pas « sauver les valeurs à la mémoire » en permanence, il est tout aussi longtemps que cette variable est dans le champ.

Voici comment vous renvoyez plusieurs valeurs, généralement en C et C++. Vous passez un pointeur sur une structure et la fonction appelée remplit la structure avec les valeurs qu'elle a calculées pour vous.

1

buf est la structure qui stat charge avec les informations sur le fichier que vous passez dans le premier paramètre. Vous passez &buf ici, car vous avez buf alloués sur la pile en tant que variable locale et vous devez passer un pointeur à la fonction stat pour lui permettre de charger les données.

Toutes les variables de st_* font partie de l'objet struct stat et doivent donc être accessibles via votre variable buf locale buf.st_uid, etc.

3

Pour un autre projet, j'ai fouetté une petite fonction qui fait quelque chose de similaire à ce dont vous avez besoin. Jetez un oeil à sprintstatf.

Voici un exemple d'utilisation:

#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdio.h> 

#include "sprintstatf.h" 

int 
main(int argc, char *argv[]) 
{ 
    char *outbuf = (char *)malloc(2048 * sizeof(char)); 
    struct stat stbuf; 
    char *fmt = \ 
     "st_atime (decimal) = \"%a\"\n" 
     "st_atime (string) = \"%A\"\n" 
     "st_ctime (decimal) = \"%c\"\n" 
     "st_ctime (string) = \"%C\"\n" 
     "st_gid (decimal) = \"%g\"\n" 
     "st_gid (string) = \"%G\"\n" 
     "st_ino    = \"%i\"\n" 
     "st_mtime (decimal) = \"%m\"\n" 
     "st_mtime (string) = \"%M\"\n" 
     "st_nlink   = \"%n\"\n" 
     "st_mode (octal) = \"%p\"\n" 
     "st_mode (string) = \"%P\"\n" 
     "st_size   = \"%s\"\n" 
     "st_uid    = \"%u\"\n" 
     "st_uid    = \"%U\"\n"; 

    lstat(argv[1], &stbuf); 

    sprintstatf(outbuf, fmt, &stbuf); 
    printf("%s", outbuf); 

    free(outbuf); 
    exit(EXIT_SUCCESS); 
} 

/* EOF */ 
1

Cette question peut être moyen de vieux pour commenter, mais je suis annonce comme référence

Pour obtenir une bonne compréhension de la fonction stat(), la raison de passer la référence stat et plus important encore la gestion des erreurs sont expliquées bien dans le lien ci-dessous

stat - get file status