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


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

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
Author: hippietrail, 2008-08-12

13 answers

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 el argumento filename un const char.
  • Se corrigió la definición de struct stat, a la que le faltaba el nombre de la variable.
  • Devuelve -1 por error en lugar de 0, lo que sería ambiguo para un archivo vacío. off_t es un tipo con signo, por lo que esto es posible.

Si quieres fsize() imprimir un mensaje de error, puedes 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 el opción -D_FILE_OFFSET_BITS=64, de 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 obtener más detalles.

 124
Author: Ted Percival,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-04 02:03:49

No use int. Los archivos de más de 2 gigabytes de tamaño son comunes como la suciedad en estos días

No use unsigned int. Los archivos de más de 4 gigabytes de tamaño son comunes como algunos dirt

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 por ahí.

Si estás en Windows, deberías usar GetFileSizeEx - it en realidad utiliza un entero de 64 bits firmado, por lo que comenzará a golpear problemas con 8 archivos exabyte. ¡Tonto Microsoft! :-)

 68
Author: Orion Edwards,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-11 22:14:19

La solución de Matt debería funcionar, excepto que es C++ en lugar de C, y el tell inicial no debería ser necesario.

unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}

También arreglé tu corsé para ti. ;)

Actualización: Esta no es realmente la mejor solución. Está limitado a archivos de 4 GB en Windows y es probable que sea más lento que solo usar una llamada específica de la plataforma como GetFileSizeEx o stat64.

 27
Author: Derek Park,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-18 04:19:28

* * No hagas esto ( ¿por qué?):

Citando el documento estándar de C99 que encontré en línea: "Establecer el indicador de posición del archivo al final del archivo, como con fseek(file, 0, SEEK_END), tiene un comportamiento indefinido para una secuencia binaria (debido a posibles caracteres nulos finales) o para cualquier secuencia con codificación dependiente del estado que no termine seguramente en el estado de cambio inicial.**

Cambie la definición a int para que los mensajes de error se puedan transmitir, y luego use fseek () y ftell () para determinar el tamaño del archivo.

int fsize(char* file) {
  int size;
  FILE* fh;

  fh = fopen(file, "rb"); //binary mode
  if(fh != NULL){
    if( fseek(fh, 0, SEEK_END) ){
      fclose(fh);
      return -1;
    }

    size = ftell(fh);
    fclose(fh);
    return size;
  }

  return -1; //error
}
 12
Author: andrewrk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-05 02:16:40

Si está de acuerdo con usar 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;
}
 5
Author: NilObject,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-01 12:26:46

Y si está construyendo una aplicación de Windows, use la API GetFileSizeEx ya que la E/S del archivo CRT es desordenada, especialmente para determinar la longitud del archivo, debido a las peculiaridades en las representaciones de archivos en diferentes sistemas;)

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-12 00:15:35

Una búsqueda rápida en Google encontró un método usando fseek y ftell y un hilo con esta pregunta con respuestas que no se puede hacer solo en C de otra manera.

Puedes usar una biblioteca de portabilidad como NSPR (la biblioteca que alimenta Firefox) o comprobar su implementación (bastante peluda).

 3
Author: Nickolay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-05 18:42:00

Utilicé 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);
 1
Author: rco16,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-08 01:54:26

Aquí hay una función simple y limpia que devuelve el tamaño del archivo.

long get_file_size(char *path)
{
    FILE *fp;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    return ftell(fp); 
}
 1
Author: Abdessamad Doughri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 15:48:17

Prueba esto {

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

Lo que hace esto es primero, buscar al final del archivo; luego, informar dónde está el puntero del archivo. Por último (esto es opcional) rebobina de nuevo al principio del archivo. Tenga en cuenta que fp debe ser un flujo binario.

File_size contiene el número de bytes que contiene el archivo. Tenga en cuenta que desde (según climits.h) el tipo largo sin signo está limitado a 4294967295 bytes (4 gigabytes) necesitará encontrar un tipo de variable diferente si es probable que trate con archivos más grandes que eso.

 1
Author: Adrian Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-19 19:47:09

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

 -1
Author: Chris Roberts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-11 21:18:31

Mirando la pregunta, ftell puede obtener fácilmente el número de bytes.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);
 -2
Author: zishan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 15:48:38

Puede abrir el archivo, ir a 0 offset 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.

 -3
Author: PabloG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-11 21:23:59