¿Cómo puedo averiguar el tamaño de un archivo, en bytes?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
andrewrk
¿Cómo puedo averiguar el tamaño de un archivo, en bytes?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
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:
const char
.struct stat
definición, a la que le faltaba el nombre de la variable.-1
por error en lugar de 0
que 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=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 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
– jugo de sig
26 de marzo de 2009 a las 5:33
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! 🙂
É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.
stat(3)
.st_size
propiedad.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);
}
É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!
#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 volver0
si el archivo es una pipa ostdin
.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
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
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
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* file
Por qué noFILE* 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
yread
. Ten cuidado.– usuario26742873
16 de febrero de 2021 a las 2:54