¿Cómo se determina el tamaño de un archivo en C?

7 minutos de lectura

avatar de usuario
andrewrk

¿Cómo puedo averiguar el tamaño de un archivo, en bytes?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}

  • Vas a necesitar usar una función de biblioteca para recuperar los detalles de un archivo. Como C es completamente independiente de la plataforma, deberá informarnos para qué plataforma / sistema operativo está desarrollando.

    – Chris Roberts

    11 de agosto de 2008 a las 21:18

  • Por qué char* filePor qué no FILE* file? -1

    usuario12211554

    12 sep 2019 a las 19:16

  • @user12211554 para que… solo strlen!

    – usuario26742873

    16 de febrero de 2021 a las 2:50


  • Tenga en cuenta que: el archivo puede crecer entre fsize y read. Ten cuidado.

    – usuario26742873

    16 de febrero de 2021 a las 2:54

avatar de usuario
ted percival

En sistemas similares a Unix, puede usar llamadas al sistema POSIX: stat en un caminoo fstat en un descriptor de archivo ya abierto (POSIX página manlinux página man).
(Obtenga un descriptor de archivo de open(2)o fileno(FILE*) en una transmisión de stdio).

Basado en el código de NilObject:

#include <sys/stat.h>
#include <sys/types.h>

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

Cambios:

  • Hizo que el argumento del nombre de archivo fuera const char.
  • Corregido el struct stat definición, a la que le faltaba el nombre de la variable.
  • Devoluciones -1 por error en lugar de 0que sería ambiguo para un archivo vacío. off_t es un tipo firmado por lo que esto es posible.

Si quieres fsize() para imprimir un mensaje de error, puede usar esto:

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
    struct stat st;

    if (stat(filename, &st) == 0)
        return st.st_size;

    fprintf(stderr, "Cannot determine size of %s: %s\n",
            filename, strerror(errno));

    return -1;
}

En sistemas de 32 bits, debe compilar esto con la opción -D_FILE_OFFSET_BITS=64de lo contrario off_t solo tendrá valores de hasta 2 GB. Consulte la sección “Uso de LFS” de Soporte de archivos grandes en Linux para detalles.

  • Esto es específico de Linux/Unix; probablemente valga la pena señalarlo, ya que la pregunta no especificó un sistema operativo.

    – Drew Pasillo

    2 de agosto de 2010 a las 21:54

  • Probablemente podría cambiar el tipo de retorno a ssize_t y convertir el tamaño de un off_t sin ningún problema. Parecería tener más sentido usar un ssize_t 🙂 (No debe confundirse con size_t que no está firmado y no se puede usar para indicar un error).

    –Ted Percival

    6 de agosto de 2010 a las 17:03

  • Para más código portátil, use fseek + ftell según lo propuesto por Derek.

    – Ciro Santilli Путлер Капут 六四事

    2 de marzo de 2015 a las 7:57


  • Para más código portátil, use fseek + ftell según lo propuesto por Derek. No. El C estándar establece específicamente que fseek() para SEEK_END en un archivo binario es un comportamiento indefinido. 7.19.9.2 El fseek función … Una secuencia binaria no necesita soportar significativamente fseek llamadas con un valor de donde SEEK_END, y como se indica a continuación, que es de la nota al pie 234 en la p. 267 de la Norma C vinculada, y que específicamente etiqueta fseek para SEEK_END en un flujo binario como comportamiento indefinido. .

    –Andrew Henle

    06/04/2016 a las 10:54

  • Desde manual de libc de gnu: … [non-POSIX] Los sistemas distinguen entre archivos que contienen texto y archivos que contienen datos binarios, y las funciones de entrada y salida de ISO C permiten esta distinción. … En la Biblioteca GNU C, y en todos los sistemas POSIX, no hay diferencia entre flujos de texto y flujos binarios. Cuando abre una transmisión, obtiene el mismo tipo de transmisión independientemente de si solicita binario. Esta secuencia puede manejar cualquier contenido de archivo y no tiene ninguna de las restricciones que a veces tienen las secuencias de texto.

    – Niño pequeño

    14 de agosto de 2020 a las 8:02

MFC de C++ extraído de los detalles del archivo de Windows, no estoy seguro de si esto funciona mejor que buscar, pero si se extrae de los metadatos, creo que es más rápido porque no necesita leer el archivo completo

ULONGLONG GetFileSizeAtt(const wchar_t *wFile)
{
    WIN32_FILE_ATTRIBUTE_DATA fileInfo;
    ULONGLONG FileSize = 0ULL;
    //https://docs.microsoft.com/nl-nl/windows/win32/api/fileapi/nf-fileapi-getfileattributesexa?redirectedfrom=MSDN
    //https://docs.microsoft.com/nl-nl/windows/win32/api/fileapi/ns-fileapi-win32_file_attribute_data?redirectedfrom=MSDN
    if (GetFileAttributesEx(wFile, GetFileExInfoStandard, &fileInfo))
    {
        ULARGE_INTEGER ul;
        ul.HighPart = fileInfo.nFileSizeHigh;
        ul.LowPart = fileInfo.nFileSizeLow;
        FileSize = ul.QuadPart;
    }
    return FileSize;
}

Puede abrir el archivo, ir a 0 desplazamiento relativo desde la parte inferior del archivo con

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

el valor devuelto por fseek es el tamaño del archivo.

No codifiqué en C durante mucho tiempo, pero creo que debería funcionar.

  • No debería tener que definir algo como SEEKBOTTOM. #include fseek(manejar, 0, SEEK_END);

    – jugo de sig

    26 de marzo de 2009 a las 5:33

avatar de usuario
Orión Edwards

no usar int. Los archivos de más de 2 gigabytes de tamaño son comunes como basura en estos días

no usar unsigned int. Los archivos de más de 4 gigabytes de tamaño son comunes como una suciedad un poco menos común.

IIRC la biblioteca estándar define off_t como un entero de 64 bits sin signo, que es lo que todos deberían usar. Podemos redefinir eso para que sea de 128 bits en unos pocos años cuando comencemos a tener archivos de 16 exabytes dando vueltas.

Si estás en Windows, deberías usar ObtenerTamañoArchivoEx – en realidad usa un entero de 64 bits con signo, por lo que comenzarán a tener problemas con archivos de 8 exabytes. ¡Microsoft tonto! 🙂

POSIX

Él POSIX estándar tiene su propio método para obtener el tamaño del archivo.

Incluir la sys/stat.h encabezado para usar la función.

Sinopsis

  • Obtener estadísticas de archivos usando stat(3).
  • Obtener el st_size propiedad.

Ejemplos

Nota: Limita el tamaño a 4GB. Que no Fat32 sistema de archivos y luego use la versión de 64 bits!

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

int main(int argc, char** argv)
{
    struct stat info;
    stat(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    struct stat64 info;
    stat64(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}

ANSI C (estándar)

Él ANSI C no proporciona directamente la forma de determinar la longitud del archivo.

Tendremos que usar nuestra mente. ¡Por ahora, usaremos el enfoque de búsqueda!

Sinopsis

  • Buscar el archivo hasta el final usando fseek(3).
  • Obtener la posición actual usando ftell(3).

Ejemplo

#include <stdio.h>

int main(int argc, char** argv)
{
    FILE* fp = fopen(argv[1]);
    int f_size;

    fseek(fp, 0, SEEK_END);
    f_size = ftell(fp);
    rewind(fp); // to back to start again

    printf("%s: size=%ld", (unsigned long)f_size);
}

Si el archivo es stdin o una pipa. POSIX, ANSI C no funcionará

va a volver 0 si el archivo es una pipa o stdin.

Opinión: Deberías usar POSIX estándar en su lugar. Porque tiene soporte de 64 bits.

  • struct _stat64 y __stat64() para ventanas.

    –Bob Stein

    17 de abril de 2019 a las 13:23


  • El último ejemplo es incorrecto, fopen toma dos argumentos

    –MM

    17 de febrero de 2021 a las 3:58

avatar de usuario
rco16

Usé este conjunto de código para encontrar la longitud del archivo.

//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");

//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);

//stores file size
long file_length = buffer.st_size;
fclose(i_file);

  • struct _stat64 y __stat64() para ventanas.

    –Bob Stein

    17 de abril de 2019 a las 13:23


  • El último ejemplo es incorrecto, fopen toma dos argumentos

    –MM

    17 de febrero de 2021 a las 3:58

avatar de usuario
pmttavara

Si está de acuerdo con el uso de la biblioteca std c:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

  • Eso no es el estándar C. Es parte del estándar POSIX, pero no del estándar C.

    – Parque Derek

    11 de agosto de 2008 a las 21:32

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad