Como posso obter o tamanho de um arquivo em C?

Duplicar Possível:
Como você determina o tamanho de um arquivo em C?

Como posso descobrir o tamanho de um arquivo? Eu abri com uma aplicação escrita em C. Eu gostaria de saber o tamanho, porque eu quero colocar o conteúdo do arquivo carregado em uma string, que eu alocar usando malloc() . Apenas escrevendo malloc(10000*sizeof(char)); IMHO é uma má ideia.

Você precisa procurar até o final do arquivo e, em seguida, pedir a posição:

 fseek(fp, 0L, SEEK_END); sz = ftell(fp); 

Você pode então buscar de volta, por exemplo:

 fseek(fp, 0L, SEEK_SET); 

ou (se procura ir para o começo)

 rewind(fp); 

Usando a biblioteca padrão:

Supondo que sua implementação tenha suporte significativo para 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:

Você pode usar stat (se você souber o nome do arquivo) ou fstat (se você tiver o descritor de arquivo).

Aqui está um exemplo para stat:

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

Win32:

Você pode usar GetFileSize ou GetFileSizeEx .

Se você tiver o descritor de arquivo, fstat() retorna uma estrutura stat que contém o tamanho do arquivo.

 #include  #include  #include  // fd = fileno(f); //if you have a stream (eg from fopen), not a file descriptor. struct stat buf; fstat(fd, &buf); off_t size = buf.st_size; 

Você considerou não computar o tamanho do arquivo e apenas aumentar a matriz, se necessário? Aqui está um exemplo (com a verificação de erros omitida):

 #define CHUNK 1024 /* Read the contents of a file into a buffer. Return the size of the file * and set buf to point to a buffer allocated with malloc that contains * the file contents. */ int read_file(FILE *fp, char **buf) { int n, np; char *b, *b2; n = CHUNK; np = n; b = malloc(sizeof(char)*n); while ((r = fread(b, sizeof(char), CHUNK, fp)) > 0) { n += r; if (np - n < CHUNK) { np *= 2; // buffer is too small, the next read could overflow! b2 = malloc(np*sizeof(char)); memcpy(b2, b, n * sizeof(char)); free(b); b = b2; } } *buf = b; return n; } 

Isso tem a vantagem de funcionar até mesmo para streams nos quais é impossível obter o tamanho do arquivo (como stdin).

Acabei fazendo apenas uma function fsize curta e doce (note, sem verificação de erros)

 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; } 

É meio bobo que a biblioteca C padrão não tenha essa function, mas eu posso ver porque seria difícil, já que nem todos os “arquivos” têm tamanho (por exemplo, /dev/null )

Se você está no Linux, considere seriamente apenas usar a function g_file_get_contents do glib. Ele lida com todo o código para carregar um arquivo, alocar memory e manipular erros.

Como usar o lseek / fseek / stat / fstat para obter o tamanho do arquivo?

 #include  #include  #include  #include  #include  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 == (long)-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 == (off_t)-1) { printf("failed to lseek %s\n", filename); exit(EXIT_FAILURE); } printf("[*] seek_filesize - file: %s, size: %lld\n", filename, 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  ...\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; } 
 #include  #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