Pergunta

Como posso descobrir o tamanho de um arquivo, em bytes?

#include <stdio.h>

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

Solução

Baseado no código do 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; 
}

Mudanças:

  • Tornou o argumento do nome do arquivo um const char.
  • Corrigido o struct stat definição, que estava faltando o nome da variável.
  • Devoluções -1 por erro em vez de 0, o que seria ambíguo para um arquivo vazio. off_t é um tipo assinado, então isso é possível.

Se você quiser fsize() para imprimir uma mensagem de erro, você pode usar isto:

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

Em sistemas de 32 bits você deve compilar isso com a opção -D_FILE_OFFSET_BITS=64, de outra forma off_t armazenará apenas valores de até 2 GB.Veja a seção "Usando LFS" do Suporte a arquivos grandes no Linux para detalhes.

Outras dicas

Não use int.Arquivos com mais de 2 gigabytes de tamanho são comuns como sujeira atualmente

Não use unsigned int.Arquivos com mais de 4 gigabytes de tamanho são comuns como alguma sujeira um pouco menos comum

IIRC, a biblioteca padrão define off_t como um número inteiro não assinado de 64 bits, que é o que todos deveriam usar.Podemos redefinir isso para 128 bits em alguns anos, quando começarmos a ter arquivos de 16 exabytes por aí.

Se você estiver no Windows, você deve usar GetFileSizeEx - na verdade, ele usa um número inteiro assinado de 64 bits, então eles começarão a ter problemas com arquivos de 8 exabytes.Microsoft tola!:-)

A solução de Matt deve funcionar, exceto que é C++ em vez de C, e a informação inicial não deve ser necessária.

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

Consertei seu aparelho para você também.;)

Atualizar:Esta não é realmente a melhor solução.É limitado a arquivos de 4 GB no Windows e provavelmente é mais lento do que apenas usar uma chamada específica da plataforma, como GetFileSizeEx ou stat64.

**Não faça isso (por que?):

Citando o documento padrão C99 que encontrei online:"Definir o indicador de posição do arquivo como fim do arquivo, como acontece com fseek(file, 0, SEEK_END), tem comportamento indefinido para um fluxo binário (devido a possíveis caracteres nulos à direita) ou para qualquer fluxo com codificação dependente de estado que não certamente não terminará no estado de mudança inicial.**

Altere a definição para int para que as mensagens de erro possam ser transmitidas e, em seguida, use fseek() e ftell() para determinar o tamanho do arquivo.

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
}

Se você concordar em usar a 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;
}

POSIX

O POSIX standard tem seu próprio método para obter o tamanho do arquivo.
Incluir o sys/stat.h cabeçalho para usar a função.

Sinopse

  • Obtenha estatísticas de arquivos usando stat(3).
  • Obtenha o st_size propriedade.

Exemplos

Observação:Limita o tamanho a 4GB.Se não Fat32 sistema de arquivos, use a versão 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 (padrão)

O ANSI-C não fornece diretamente a maneira de determinar o comprimento do arquivo.
Teremos que usar nossa mente.Por enquanto, usaremos a abordagem de busca!

Sinopse

  • Procure o arquivo até o final usando fseek(3).
  • Obtenha a posição atual usando ftell(3).

Exemplo

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

Se o arquivo for stdin ou um cano. POSIX, ANSI C não vai funcionar.
Irá retornar 0 se o arquivo for um pipe ou stdin.

Opinião:Você deveria usar POSIX padrão em vez disso.Porque tem suporte para 64 bits.

E se você estiver criando um aplicativo do Windows, use o GetFileSizeEx API como E/S de arquivo CRT é confusa, especialmente para determinar o comprimento do arquivo, devido a peculiaridades nas representações de arquivos em diferentes sistemas;)

Uma pesquisa rápida no Google encontrou um método usando fseek e ftell e um tópico com esta pergunta com respostas de que isso não pode ser feito apenas em C de outra maneira.

Você poderia usar uma biblioteca de portabilidade como NSPR (a biblioteca que alimenta o Firefox) ou verifique sua implementação (bastante peludo).

Usei esse conjunto de código para encontrar o comprimento do arquivo.

//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);

Tente isto -

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

O que isso faz é primeiro buscar o final do arquivo;em seguida, informe onde está o ponteiro do arquivo.Por último (opcional), ele volta ao início do arquivo.Observe que fp deve ser um fluxo binário.

file_size contém o número de bytes que o arquivo contém.Observe que, como (de acordo com clilimits.h) o tipo longo não assinado é limitado a 4294967295 bytes (4 gigabytes), você precisará encontrar um tipo de variável diferente se for provável que lide com arquivos maiores que isso.

Aqui está uma função simples e limpa que retorna o tamanho do arquivo.

long get_file_size(char *path)
{
    FILE *fp;
    long size = -1;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size = ftell(fp); 
    fp.close();
    return 
}

Você precisará usar uma função de biblioteca para recuperar os detalhes de um arquivo.Como C é completamente independente de plataforma, você precisará nos informar para qual plataforma/sistema operacional você está desenvolvendo!

Olhando para a pergunta, ftell pode facilmente obter o número de bytes.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

Você pode abrir o arquivo, ir para o deslocamento 0 relativo à parte inferior do arquivo com

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

o valor retornado de fseek é o tamanho do arquivo.

Faz muito tempo que não codifico em C, mas acho que deve funcionar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top