quinta-feira, 9 de setembro de 2010

Lendo arquivos em ANSI C diretamente para a Memória

Uma das coisas que me chama a atenção na linguagem C é a sua flexibilidade.
Ontem um amigo me mostrou um código de um analisador léxico, que está trabalhando para uma matéria da faculdade e vi que estava lendo um arquivo de texto e testando seus tokens a cada iteração do loop, em quanto não era fim do arquivo. Eu então sugeri que ele fizesse a leitura do arquivo para a memória e aí começou a dúvida. Como ler um arquivo em C diretamente para a memória?
Segue a solução que pode ajudar mais pessoas com esta mesma dúvida:


#include <stdio.h>

int main(int argc, char *argv[])
{
    char *mem;
    int size;
    FILE *f;
    
    f = fopen("arquivo.txt", "rb"); 
    
    if (f == NULL) exit(1); 
    
    fseek(f, 0, SEEK_END); 
    size = ftell(f); 
    fseek(f, 0, SEEK_SET);
    
    mem = (char *)malloc(size+1); 
    
    if (size != fread(mem, sizeof(char), size, f)) { 
        free(mem);
        exit(2);
    } 
    
    fclose(f);
    
    free(mem);
    
    return 0;
}

Como podemos perceber neste código, para obter o tamanho do arquivo, primeiramente usamos a função fseek() para posicionar o ponteiro dentro do arquivo, passando como referência SEEK_END que faz com que o ponteiro seja posicionado no final do arquivo. Logo depois chamamos a função ftell() que retorna a quantidade de bytes no arquivo, do início até a posição do ponteiro. Como posicionamos o ponteiro no final do arquivo, ele retornará o tamanho do arquivo em bytes.

Retornamos então o ponteiro para o inicio do arquivo, chamando novamente a função fseek() e passando para ela o argumento SEEK_SET, que irá posicionar o ponteiro novamente no início do arquivo.
Depois de alocar memória, utilizando a função malloc, lemos o arquivo para dentro da variável mem utilizando a função fread(), que retorna a quantidade de bytes lidos. Neste retorno, comparamos se a quantidade de bytes lidos corresponde a quantidade de bytes do arquivo. Caso não seja verdadeiro, ele emitirá um erro e saíra do programa, liberando a memória.
Para mais informações para fseek(), ftell() e fread() e outras funções para tratamento de arquivos, visite o  endereço: http://www.cplusplus.com/reference/clibrary/cstdio/

Breno
Compartilhe:

0 comentários:

QuaseHard. Tecnologia do Blogger.