¿Cómo puedo saber el tamaño de un archivo que abrí con una aplicación escrita en C? Me gustaría saber el tamaño, porque quiero poner el contenido del archivo cargado en una cadena, que asigno usando malloc()
. solo escribiendo malloc(10000*sizeof(char));
es en mi humilde opinión una mala idea.
¿Cómo puedo obtener el tamaño de un archivo en C? [duplicate]
[*]
nino
Rob Walker
Debe buscar hasta el final del archivo y luego solicitar la posición:
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
A continuación, puede buscar hacia atrás, por ejemplo:
fseek(fp, 0L, SEEK_SET);
o (si busca ir al principio)
rewind(fp);
-
@camh – Gracias hombre. Este comentario resolvió un problema que tenía con un algoritmo de tamaño de archivo. Para el registro, uno abre un archivo en modo binario poniendo una ‘b’ al final de la cadena de modo de fopen.
– TED
18 de mayo de 2010 a las 10:42
-
Tú, uh, usa
rewind
antes de que la gente olvide lo que significa– bobobobo
23 de septiembre de 2011 a las 16:55
-
Devuelve un int firmado, por lo que está limitado a 2 GB. Pero en el lado positivo, su archivo podría tener una longitud negativa de 2 mil millones de bytes, y están preparados para eso.
– set
13 de febrero de 2012 a las 21:07
-
length = lseek(fd, 0, SEEK_END)+1;
– Volodymyr M. Lisivka
16 de noviembre de 2012 a las 16:24
-
Desde documentación fseek “Se permite que las implementaciones de la biblioteca no admitan SEEK_END de manera significativa (por lo tanto, el código que la usa no tiene una portabilidad estándar real)”.
– Mika Haarahiltunen
02/09/2013 a las 10:43
greg hewgill
Usando la biblioteca estándar:
Suponiendo que su implementación admita significativamente SEEK_END:
fseek(f, 0, SEEK_END); // seek to end of file
size = ftell(f); // get current file pointer
fseek(f, 0, SEEK_SET); // seek back to beginning of file
// proceed with allocating memory and reading the file
Linux/POSIX:
Puedes usar stat
(si conoce el nombre del archivo), o fstat
(si tiene el descriptor de archivo).
Aquí hay un ejemplo para stat:
#include <sys/stat.h>
struct stat st;
stat(filename, &st);
size = st.st_size;
Win32:
Puedes usar ObtenerTamañoArchivo o ObtenerTamañoArchivoEx.
-
Tenga en cuenta que he omitido la verificación de errores en aras de la claridad.
– Greg Hewgill
26 de octubre de 2008 a las 21:23
-
No necesita el nombre del archivo; puede usar fstat para eso.
– Tanktalus
26 de octubre de 2008 a las 21:24
-
Debe señalar la dirección de la estructura. La segunda línea debería ser: stat(filename, &st);
– Vlad el Impala
3 de noviembre de 2009 a las 21:16
-
He omitido la verificación de errores en aras de -ERROR FATAL, SALIENDO.
-Buttle Butkus
3 de febrero de 2012 a las 9:55
-
La segunda opción es la única que puede mostrar archivos de más de 2 GB.
– set
13 de febrero de 2012 a las 21:52
Flautista de Hamelín
Si tiene el descriptor de archivo fstat()
devuelve una estructura estadística que contiene el tamaño del archivo.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// fd = fileno(f); //if you have a stream (e.g. from fopen), not a file descriptor.
struct stat buf;
fstat(fd, &buf);
off_t size = buf.st_size;
-
Agregue “fd = fileno(f);” si tiene una transmisión (por ejemplo, de fopen), no un descriptor de archivo. Necesita comprobación de errores.
– ysth
26 de octubre de 2008 a las 21:24
-
Por supuesto, necesita verificación de errores, eso solo complicaría el ejemplo.
– Flautista de Hamelín
26 de octubre de 2008 a las 21:28
-
esta es, en mi opinión, la mejor respuesta real, y creo que todos tenemos nuestras ruedas de entrenamiento apagadas en su mayor parte en C, ¿realmente necesitamos la verificación de errores y otro código innecesario en nuestros ejemplos? el de ellos, no hagamos lo mismo, sino que digamos al final ‘asegúrese de agregar la verificación de errores’ y terminemos con eso.
– osirisgothra
7 de noviembre de 2013 a las 16:45
-
MUCHOS de los usuarios de SO son estudiantes de C, no maestros anteriores. Por lo tanto, el código dado en las respuestas debe mostrar la verificación de errores, para que el estudiante aprenda la forma correcta de codificar.
– usuario3629249
23/02/2015 a las 18:30
-
existe el detalle de que (f)stat() devuelve los bytes totales de asignación de bloques mientras que la secuencia fseek() / ftell() devuelve el número de bytes antes de que se encuentre EOF.
– usuario3629249
23 de febrero de 2015 a las 18:32
Cómo utilizar busco/buscar/estadística/fstat para obtener tamaño de archivo?
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
void
fseek_filesize(const char *filename)
{
FILE *fp = NULL;
long off;
fp = fopen(filename, "r");
if (fp == NULL)
{
printf("failed to fopen %s\n", filename);
exit(EXIT_FAILURE);
}
if (fseek(fp, 0, SEEK_END) == -1)
{
printf("failed to fseek %s\n", filename);
exit(EXIT_FAILURE);
}
off = ftell(fp);
if (off == -1)
{
printf("failed to ftell %s\n", filename);
exit(EXIT_FAILURE);
}
printf("[*] fseek_filesize - file: %s, size: %ld\n", filename, off);
if (fclose(fp) != 0)
{
printf("failed to fclose %s\n", filename);
exit(EXIT_FAILURE);
}
}
void
fstat_filesize(const char *filename)
{
int fd;
struct stat statbuf;
fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
if (fd == -1)
{
printf("failed to open %s\n", filename);
exit(EXIT_FAILURE);
}
if (fstat(fd, &statbuf) == -1)
{
printf("failed to fstat %s\n", filename);
exit(EXIT_FAILURE);
}
printf("[*] fstat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
if (close(fd) == -1)
{
printf("failed to fclose %s\n", filename);
exit(EXIT_FAILURE);
}
}
void
stat_filesize(const char *filename)
{
struct stat statbuf;
if (stat(filename, &statbuf) == -1)
{
printf("failed to stat %s\n", filename);
exit(EXIT_FAILURE);
}
printf("[*] stat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
}
void
seek_filesize(const char *filename)
{
int fd;
off_t off;
if (filename == NULL)
{
printf("invalid filename\n");
exit(EXIT_FAILURE);
}
fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
if (fd == -1)
{
printf("failed to open %s\n", filename);
exit(EXIT_FAILURE);
}
off = lseek(fd, 0, SEEK_END);
if (off == -1)
{
printf("failed to lseek %s\n", filename);
exit(EXIT_FAILURE);
}
printf("[*] seek_filesize - file: %s, size: %lld\n", filename, (long long) off);
if (close(fd) == -1)
{
printf("failed to close %s\n", filename);
exit(EXIT_FAILURE);
}
}
int
main(int argc, const char *argv[])
{
int i;
if (argc < 2)
{
printf("%s <file1> <file2>...\n", argv[0]);
exit(0);
}
for(i = 1; i < argc; i++)
{
seek_filesize(argv[i]);
stat_filesize(argv[i]);
fstat_filesize(argv[i]);
fseek_filesize(argv[i]);
}
return 0;
}
ben combee
Si está en Linux, considere seriamente simplemente usar el g_file_get_contents función de glib. Maneja todo el código para cargar un archivo, asignar memoria y manejar errores.
-
Si estás en Linux y quiero tener una dependencia de glib, eso es.
– JesperE
26 de octubre de 2008 a las 22:25
-
No es un problema tan malo, ya que ahora las aplicaciones GTK y KDE utilizan glib. También está disponible en Mac OS X y Windows, pero no es tan estándar allí.
– Ben Combee
29 de octubre de 2008 a las 19:23
-
¿Pero no es glib una biblioteca de C++? La pregunta estipulada C
– Dave Appleton
21 de junio de 2013 a las 9:54
-
@DaveAppleton: No, glib es en gran medida una biblioteca C simple, no C ++.
– Nate CK
20 de febrero de 2014 a las 4:13
-
@BenCombee glib no está en Android, la última vez que lo comprobé.
– Wyatt Ward
1 de mayo de 2017 a las 4:40
condez
Terminé haciendo un breve y dulce fsize
función (nota, sin comprobación de errores)
int fsize(FILE *fp){
int prev=ftell(fp);
fseek(fp, 0L, SEEK_END);
int sz=ftell(fp);
fseek(fp,prev,SEEK_SET); //go back to where we were
return sz;
}
Es un poco tonto que la biblioteca C estándar no tenga esa función, pero puedo ver por qué sería difícil ya que no todos los “archivos” tienen un tamaño (por ejemplo /dev/null
)
-
Si estás en Linux y quiero tener una dependencia de glib, eso es.
– JesperE
26 de octubre de 2008 a las 22:25
-
No es un problema tan malo, ya que ahora las aplicaciones GTK y KDE utilizan glib. También está disponible en Mac OS X y Windows, pero no es tan estándar allí.
– Ben Combee
29 de octubre de 2008 a las 19:23
-
¿Pero no es glib una biblioteca de C++? La pregunta estipulada C
– Dave Appleton
21 de junio de 2013 a las 9:54
-
@DaveAppleton: No, glib es en gran medida una biblioteca C simple, no C ++.
– Nate CK
20 de febrero de 2014 a las 4:13
-
@BenCombee glib no está en Android, la última vez que lo comprobé.
– Wyatt Ward
1 de mayo de 2017 a las 4:40
ensambladorplan9
#include <stdio.h>
#define MAXNUMBER 1024
int main()
{
int i;
char a[MAXNUMBER];
FILE *fp = popen("du -b /bin/bash", "r");
while((a[i++] = getc(fp))!= 9)
;
a[i] ='\0';
printf(" a is %s\n", a);
pclose(fp);
return 0;
}
HTH
-
Esta solución es innecesariamente compleja e ineficiente. No es necesario ejecutar un comando y analizar su salida, como lo aclaran las respuestas anteriores.
– brandizzi
12 de marzo de 2011 a las 15:16
-
Además, esta es una solución solo para Linux
– bobobobo
23 de septiembre de 2011 a las 16:57
Tenga en cuenta que sizeof(char) es 1, por definición.
– Randy Proctor
29 de octubre de 2009 a las 13:44
Sí, pero el compilador de alguna plataforma esotérica podría definir char como 2 bytes, entonces el programa asigna más de lo necesario. Uno nunca puede estar demasiado seguro.
–Nathan Osman
5 de enero de 2010 a las 2:50
@George un “compilador de plataforma esotérica” donde sizeof(char) != 1 no es un verdadero compilador de C. Incluso si un carácter es de 32 bits, seguirá devolviendo 1.
– Andrew Flanagan
6 de diciembre de 2010 a las 17:03
@George: El estándar C (y C++) garantiza que
sizeof(char)==1
. Ver por ejemploparashift.com/c++-faq-lite/intrinsic-types.html#faq-26.1– sleske
8 de febrero de 2011 a las 13:40
en realidad prefiero
malloc(x*sizeof(char));
paramalloc(x);
al asignar x caracteres. Sí, siempre compilan lo mismo, pero me gusta la coherencia con otras asignaciones de memoria.– forma fundida
16 de abril de 2011 a las 1:16