Manipulação Avançada de Arquivos #10

Leitura, escrita e manipulação avançada de arquivos em C.

17-11-2024 12:00

Manipulação Avançada de Arquivos

Clique aqui para ler pelo PDF e melhorar a experiência

Manipulação Avançada de Arquivos

Na Semana 10, vamos explorar técnicas avançadas de manipulação de arquivos em C. Ao trabalhar com arquivos grandes ou realizar processamento de dados mais complexos, é essencial entender como ler e escrever dados de maneira eficiente, bem como como posicionar-se no arquivo para acessar dados específicos de forma eficiente.

1. Leitura e Escrita de Arquivos Linha por Linha

A leitura e escrita linha por linha são operações comuns quando você precisa processar arquivos de texto. Em C, para ler um arquivo linha por linha, usamos a função fgets, que permite ler até o final da linha ou até que o tamanho máximo seja atingido.

Leitura de Arquivo Linha por Linha

Aqui está um exemplo de como ler um arquivo linha por linha usando fgets:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("exemplo.txt", "r");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    char linha[256];
    while (fgets(linha, sizeof(linha), arquivo)) {
        printf("%s", linha); // Exibe cada linha do arquivo
    }

    fclose(arquivo);
    return 0;
}

Neste código, o fgets lê cada linha do arquivo e a imprime até atingir o final do arquivo (EOF). Cada linha lida é armazenada na variável linha.

Escrita de arquivo por linha

Para escrever em um arquivo linha por linha, podemos usar a função fputs. Aqui está um exemplo simples:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("saida.txt", "w");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    const char *linha = "Este eh um exemplo de escrita em arquivo.\n";
    fputs(linha, arquivo); // Escreve a linha no arquivo

    fclose(arquivo);
    return 0;
}

2. Manipulação de Arquivos Grandes

Ao lidar com arquivos grandes, a leitura e escrita linha por linha podem ser ineficientes, especialmente se o arquivo contiver milhões de linhas ou for de tamanho muito grande. Uma alternativa eficiente é ler ou escrever dados em blocos usando funções como fread e fwrite.

Leitura de Arquivos Grandes em Blocos

Exemplo de como ler um arquivo binário em blocos:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("grande_arquivo.bin", "rb");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    char buffer[1024]; // Buffer para armazenar blocos de dados
    size_t bytesLidos;
    
    while ((bytesLidos = fread(buffer, 1, sizeof(buffer), arquivo)) > 0) {
        // Processa o bloco de dados lido
        printf("Lidos %zu bytes\n", bytesLidos);
    }

    fclose(arquivo);
    return 0;
}

Neste exemplo, o arquivo é lido em blocos de 1024 bytes, o que permite processar grandes volumes de dados sem sobrecarregar a memória.

Escrita de Arquivos Grandes em Blocos

Escrever grandes quantidades de dados também pode ser feito de forma eficiente em blocos com fwrite:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("saida.bin", "wb");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    char buffer[1024] = {0}; // Dados a serem escritos
    size_t bytesEscritos = fwrite(buffer, 1, sizeof(buffer), arquivo);

    printf("Escritos %zu bytes\n", bytesEscritos);

    fclose(arquivo);
    return 0;
}

3. Funções de Posicionamento no Arquivo

Em alguns casos, você pode precisar posicionar-se em um ponto específico de um arquivo, seja para ler ou escrever em uma parte específica do arquivo. Para isso, em C, usamos as funções fseek e ftell.

fseek – Posicionamento no Arquivo

A função fseek é usada para mover o ponteiro de leitura/escrita do arquivo para uma posição específica. Ela recebe três parâmetros:

Exemplo de uso do fseek:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("exemplo.txt", "r");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    fseek(arquivo, 10, SEEK_SET); // Move o ponteiro para 10 bytes a partir do início do arquivo

    char c = fgetc(arquivo); // Lê o próximo caractere
    printf("Caractere na posicao 10: %c\n", c);

    fclose(arquivo);
    return 0;
}

ftell – Obtendo a Posição Atual no Arquivo

A função ftell retorna a posição atual do ponteiro de leitura/escrita no arquivo.

Exemplo de uso do ftell:

#include <stdio.h>

int main() {
    FILE *arquivo = fopen("exemplo.txt", "r");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    fseek(arquivo, 5, SEEK_SET); // Move o ponteiro para 5 bytes a partir do início
    long pos = ftell(arquivo);   // Obtém a posição atual
    printf("Posicao atual do ponteiro: %ld\n", pos);

    fclose(arquivo);
    return 0;
}

4. Criação de Programas para Processamento de Arquivos

Salvar Dados de um Sistema de Cadastro em Arquivos

Suponha que você tenha um sistema de cadastro de pessoas, onde as informações (nome, idade, etc.) de cada pessoa devem ser armazenadas em um arquivo de texto.

Exemplo de programa simples para salvar dados de cadastro:

#include <stdio.h>

struct Pessoa {
    char nome[50];
    int idade;
};

int main() {
    FILE *arquivo = fopen("cadastro.txt", "a");
    if (arquivo == NULL) {
        printf("Erro ao abrir o arquivo\n");
        return 1;
    }

    struct Pessoa pessoa;
    printf("Digite o nome: ");
    fgets(pessoa.nome, sizeof(pessoa.nome), stdin);
    printf("Digite a idade: ");
    scanf("%d", &pessoa.idade);

    fprintf(arquivo, "Nome: %sIdade: %d\n", pessoa.nome, pessoa.idade);
    fclose(arquivo);
    printf("Cadastro salvo com sucesso!\n");

    return 0;
}

5. Processamento de Logs e Relatórios

Os arquivos de log e relatórios são frequentemente utilizados para registrar a execução de sistemas e gerar relatórios de atividades. Um exemplo simples seria um programa que grava logs em um arquivo.

Exemplo de Geração de Logs

#include <stdio.h>

int main() {
    FILE *log = fopen("log.txt", "a");
    if (log == NULL) {
        printf("Erro ao abrir o arquivo de log\n");
        return 1;
    }

    fprintf(log, "Inicio da execucao do programa\n");
    fprintf(log, "Operacao concluida com sucesso\n");

    fclose(log);
    return 0;
}

Neste exemplo, as mensagens de log são gravadas ao final do arquivo, para manter o histórico das operações.

6. Exercícios práticos

  1. Leitura Linha por Linha: Crie um programa que leia um arquivo de texto e conte o número de linhas.

  2. Gravação Linha por Linha: Desenvolva um programa que leia um arquivo de texto e grave as linhas em um novo arquivo.

  3. Leitura e Escrita de Arquivo Binário: Crie um programa para ler um arquivo binário e exibir seu conteúdo em hexadecimal.

  4. Posicionamento no Arquivo: Implemente um programa que leia um arquivo e imprima a posição atual do ponteiro após cada leitura.

  5. Cadastro de Usuários em Arquivo: Crie um programa que registre dados de cadastro de usuários em um arquivo de texto, incluindo nome, email e idade.

  6. Processamento de Log: Escreva um programa que simule um processo de log de um sistema e registre erros e sucessos em um arquivo.

7. Conclusão

Nesta semana, você aprendeu sobre técnicas avançadas de manipulação de arquivos, como leitura e escrita de arquivos grandes, posicionamento dentro de arquivos, e o processamento de arquivos de log e relatórios. Ao dominar essas técnicas, você estará apto a manipular arquivos de forma eficiente e implementar soluções mais avançadas para sistemas que exigem persistência de dados.

[Voltar ao Topo]