2010-08-18 24 views
8

Estoy tratando de encontrar la forma exacta de usar stat() para capturar información sobre un archivo. Lo que necesito es poder imprimir varios campos de información sobre un archivo. Entonces ...Uso 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; 
    ... 
} 

Estoy completamente confundido acerca de cómo hacer esto. ¿Por qué & buf es un parámetro para stat? No me importa almacenar esta información en la memoria, solo necesito los campos de salida dentro de mi programa C++. ¿Cómo accedo a la información contenida en la estructura? Se supone que buf realmente contiene la información devuelta de stat()?

+0

veo, gracias a todos por las respuestas. Fueron bastante útiles. ¿Alguien sabe cómo usar stdin, stdout o stderr como parámetros para stat works? Estas son transmisiones y no archivos, entonces, ¿cómo puede una base de datos llenar una estructura con datos? –

+0

Use 'fstat', que toma un descriptor de archivo como primer argumento en lugar de una ruta. –

+0

Normalmente haría esto pero el entorno es algo artificial ya que esta es la parte del sistema operativo de un simulador arquitectónico que he escrito. Entonces, cuando un syscall abre un archivo, tengo mi propio vector para actuar como una tabla de descriptores de archivos. ¿Hay una buena manera de capturar el descriptor de archivo real en la máquina para un archivo cuando se abre? Si ese fuera el caso, usaría fstat porque no se requeriría traducción entre las estadísticas del flujo y las estadísticas del archivo. –

Respuesta

11

Sí, buf se está utilizando aquí como un parámetro de salida. Los resultados se almacenan en buf y el valor de retorno de stat es un código de error que indica si la operación stat tuvo éxito o falló.

Se hace así porque stat es una función POSIX, diseñada para C, que no admite mecanismos de notificación de errores fuera de banda como excepciones. Si statdevolviera una estructura, entonces no tendría manera de indicar errores. El uso de este método de parámetros externos también le permite a la persona que llama elegir dónde quiere almacenar los resultados, pero esa es una característica secundaria. Está perfectamente bien pasar la dirección de una variable local normal, tal como lo has hecho aquí.

Tiene acceso a los campos de una estructura como lo haría con cualquier otro objeto. Supongo que al menos estás familiarizado con la notación de objetos. P.ej. se accede al campo st_dev dentro de la estructura stat llamada buf al buf.st_dev. Por lo tanto:

cout << buf.st_dev << endl; 

etc.

2

usted tiene varios errores en su código:

  • Usted necesita &buf, con un solo 'f'.
  • Tienes que decir, por ejemplo, buf.st_dev al imprimir, ya que st_dev es un campo en la variable struct.

Desde buf es una variable local en la pila, usted no está "salvar los valores de la memoria" de forma permanente, es el mismo tiempo que esa variable es en el estudio.

Así devuelve varios valores, normalmente, en C y C++. Pasa un puntero a una estructura, y la función que se llama rellena la estructura con los valores que ha calculado para usted.

1

buf es la estructura que stat las cargas con la información sobre el archivo que se pasa en el primer parámetro. Pase &buf aquí b/c tiene buf asignado en la pila como una variable local y debe pasar un puntero a la función de estadísticas para que pueda cargar los datos.

Todas las variables de st_* son parte del objeto struct stat y por lo tanto se debe acceder a través de su buf variable local como buf.st_uid, etc.

3

Para otro proyecto, he prepararon rápidamente una pequeña función que hace algo similar a lo que necesitas Eche un vistazo al sprintstatf.

Aquí hay un ejemplo de uso:

#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

Esta pregunta puede ser manera de edad para comentar función, pero estoy publicando esto como una referencia

Para obtener una buena comprensión de stat(), el motivo de la transmisión de la referencia estadística y más importante es el control de errores se explican bien en el siguiente enlace

stat - get file status