2010-03-02 11 views
8

Hice una función simple, que obtiene el tamaño de un archivo.¿Cómo obtener el tamaño de un archivo que es mayor a 4 Gb?

int file_size(char * filename) 
{ 
    int size; 
    struct stat st; 

    stat(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 

Se está trabajando muy bien, pero si tengo un archivo que el tamaño es más grande que 4 Gb de lo que reciba un número negativ espalda, y, por supuesto, este no es el tamaño de archivo correcto. Entonces, ¿cómo puedo obtener el tamaño de un archivo tan grande? Creo que el valor de retorno debería ser algo así como int, pero no sé qué, y no creo, eso resolvería mi problema.

Gracias,

Kampi

Actualización:

Hola!

Encontré la solución. Tengo que usar __stat64. Modifiqué mi función, y ahora está recuperando el tamaño real. Lo probé con un archivo grande de 8Gb.

unsigned long long int file_size(char * filename) 
{ 
    unsigned long long int size; 
    struct __stat64 st; 

    __stat64(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 

Y un aviso:

cuando solía printf, tuve que usar "% I64d" para imprimirlo.

+0

¿Qué sucede si cambia 'int' a' off_t', o si no está disponible, 'size_t'? Tanto en el tipo de devolución como en la declaración de 'size'. –

Respuesta

3

Probablemente pueda usar _stat64.

+0

Muchas gracias, esta fue la manera más fácil de resolver mi problema. – kampi

5

Puede usar la función Win32 GetFileSizeEx.

HANDLE aFile = CreateFile 
(
    filename, 
    FILE_READ_ATTRIBUTES, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL, 
    NULL 
); 

if (aFile != INVALID_HANDLE_VALUE) 
{ 
    long long aSize; 
    GetFileSizeEx(aFile, &aSize); 

    CloseHandle(aFile); 
    return aSize; 
} 
else 
    return -1; 
+0

La única advertencia con esto podría ser (no muy seguro) que podría ser difícil mezclar y combinar llamadas posix con llamadas de win32 dentro del mismo proceso. Parece que el OP podría venir desde un fondo de Unix y querer usar solo llamadas posix. –

0

creo, el problema es debido al tamaño de archivo más de INT_MAX, de modo que le está dando valores negativos.

Probablemente puede hacer el tipo de conversión para el tipo de datos largo, puede funcionar.

De lo contrario, use, fseek, ftell function. luego reste el puntero del archivo final desde el puntero del archivo de inicio. También le dará tamaño de archivo. (número de bytes).

1

st_size se define siempre en wchar.h, por lo que probablemente podría intentar con largo, en lugar de int

struct stat { 
    .... 
    _off_t  st_size; 
    .... 
} 

.... 

typedef long _off_t; 

Puede ser así

long file_size(char * filename) 
{ 
    long size; 
    struct stat st; 

    stat(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 
+1

No hay razón por la que no pueda anotar "sin firmar", ya que es poco probable que el tamaño del archivo sea negativo. –

+2

Si el truncamiento ocurre en st.st_size, tengo curiosidad por saber cómo asignarlo a una longitud ayuda en esta situación. – Arun

3

En tales casos, el valor de retorno de stat() podría ser -1 y errno establecido en EOVERFLOW.

La página del manual para stat en mi (máquina x86 de 64 bits) dice:

EOVERFLOW

(stat()) ruta hace referencia a un archivo cuyo tamaño no se puede representar en el tipo off_t.Esto puede ocurrir cuando una aplicación compilado en una plataforma de 32 bits sin -D_FILE_OFFSET_BITS = 64 llama stat() en un archivo cuyo tamaño supera (2 < < 31) -1 bits.

Cuestiones relacionadas