16 ARQUIVOS Um arquivo corresponde a um conjunto de informações (exemplo: uma estrutura de dados-registro), que pode ser armazenado em um dispositivo de memória permanente, exemplo disco rígido. As operações básicas para manipulação de arquivos são: abertura e fechamento do arquivo, leitura, gravação e exclusão de dados (exemplo registros). 16.1 TIPOS DE ARQUIVOS Os dados dos arquivos podem ser armazenados/acessados basicamente de dois modos: sequencial ou direto (randômico). 16.1.1 Sequencial Os dados são gravados no arquivo de forma contínua, um após o outro. A localização de qualquer um dos dados é indeterminada, para ter acesso a um dado específico é necessário percorrer todos os que o antecedem e para gravar um novo dado é necessário encontrar o final do arquivo. 16.1.2 Direto (Randômico) Neste tipo de arquivo os dados (registros) são acessados de forma direta, ou seja, através de algum de seus campos definido como chave, pode-se então acessar os dados (demais campos do registro), sem a necessidade de processar os registros que estão fisicamente antes dele no arquivo. 16.1.2.1 Arquivo Indexado (Arquivo sequencial de acesso direto) Normalmente é composto por mais de um arquivo: um arquivo de índices (chaves) que contém a posição (endereço) de cada registro no outro arquivo de dados. 16.2 TRATAMENTO DE ARQUIVOS EM LINGUAGEM C 16.2.1 Leitura e Gravação em Disco 1) Caracter: os dados são lidos e escritos caracter a caracter. getc(file); putc(char, file); Professor: Ivo Mário Mathias 66
2) string: os dados são lidos e escritos como strings. fgets(string, tam-max, file); fputs(string, file); 3) Formatado: os dados são lidos e escritos de modo formatado. fscanf(ptr_file, formato, var_ destino); fprintf(ptr_file, formato, var_destino); 4) Bloco: os dados são lidos e escritos num formato chamado registro ou bloco. Este é um grupo de dados de tamanho fixo e é usado para armazenar uma sequência de dados com itens similares, como matrizes e estruturas. fread(estrutura, tam-estrutura, qtde, ptr_file); fwrite(estrutura, tam-estrutura, qtde, ptr_file); 16.3 FORMAS DE ABERTURA 16.3.1 Modo texto Sequências de caracteres agrupadas em linhas. Números são guardados como cadeias de caracteres. Linhas são separadas por: UNIX: único caractere chamado de nova linha (LF), de código ASCII 10 decimal. DOS: cada linha é separada por dois caracteres, o caracter 13 decimal (CR) e o caracter 10 decimal (LF). Compilador C: Converte CR/LF para LF quando um arquivo é lido Converte de LF para CR/LF quando o arquivo é gravado. Indicação de fim de arquivo é enviada pelo DOS e é reconhecida pelo compilador C. 16.3.2 Modo binário Números são armazenados como estão na memória (2 bytes para inteiro, 4 para float, 8 para double ). Nenhuma conversão é feita. Qualquer caractere é lido ou gravado sem alteração. Indicação de fim de arquivo não é reconhecida, sendo interpretada como outro caracter qualquer. Obs: Principais diferenças entre modo texto e modo binário: caracter de nova linha e fim de arquivo, e forma de representar os números. 16.4 ABRINDO ARQUIVOS EM DISCO Arquivo stdio.h define a estrutura FILE que será usada para declarar arquivos. Contém informações sobre o arquivo a ser usado: seu tamanho atual, localização de seus buffers de dados, se o arquivo está sendo lido ou gravado. Professor: Ivo Mário Mathias 67
Função fopen: executa duas tarefas: 1) Preenche a estrutura FILE com as informações necessárias para o programa e para o sistema operacional; 2) Retorna um ponteiro do tipo FILE que aponta para a localização na memória da estrutura. Sintaxe: fopen("nome_do_arquivo","modo"); Exemplo de abertura e tratamento: FILE *fptr; fptr = fopen("arqlivro.arq","w"); ou FILE *fptr; if ((fptr = fopen("arqlivro.arq","w")) == NULL { printf("não é possível abrir o arquivo"); exit(0); NULL - corresponde a uma macro definida em STDIO.H, que detecta qualquer erro na abertura do arquivo (exemplo: disco protegido contra gravação, cheio, etc.) caso contrário fopen retorna o ponteiro (endereço) para a estrutura do arquivo na memória; exit() - esta função faz com que haja um terminação imediata do programa não importando de onde é chamada. Por convenção, um valor retornado ao SO significa término com sucesso, qualquer outro indica que o programa terminou por causa de algum problema. 16.4.1 Tipo de abertura dos arquivos: "r": abre arquivo texto para leitura (o arquivo deve existir). "w": abre arquivo texto para gravação. Se o arq. já existe ele é destruído, senão, um novo é criado. "a": abre arquivo texto para gravação. Os dados serão adicionados ao final do arquivo existente ou um novo arquivo será criado. "r+": abre um arquivo texto para leitura e gravação. O arquivo deve existir e pode ser atualizado. Professor: Ivo Mário Mathias 68
"w+": abre um arquivo texto para leitura e gravação. Se o arquivo existir ele será destruído e reinicializado, senão será criado. "a+": abre um arquivo texto para atualizações e para adicionar novos dados no final do arquivo existente ou um novo arquivo será criado. "a+b": Abre um arquivo binário para leitura e gravação. Se o arquivo existir, os dados serão adicionados no seu final, caso o arquivo não exista ele será criado. mesmos para arquivos binários com a letra "rb", "wb", "ab", "rb+", "wb+". 16.5 LEITURA E ESCRITA Funções fwrite e fread permitem ler e escrever blocos de dados (estruturas, matrizes) em arquivos de disco; Sintaxe: fwrite(&informação, num_bytes, itens, file) fread(&informação, num_bytes, itens, file) &informação - ponteiro para a informação que será escrita/lida (arquivo/memória); num_bytes - o número de bytes (tamanho) para ler/escrever; itens - quantidade de itens (estruturas) - (cada um tendo num_bytes de tamanho); file - ponteiro para o arquivo previamente aberto; fread - retorna o número de itens lidos; fwrite - retorna o número de itens escritos; Exemplos: if (fwrite(&livro, sizeof(livro), 1, fptr)!=1){ printf ("Erro de escrita no arquivo"); fclose(fptr); if (fread(&livro, sizeof(livro), 1, fptr)!=1) { if (feof(fptr)) { fclose(fptr); Professor: Ivo Mário Mathias 69
Observação: sizeof - operador que é usado para computar o tamanho de qualquer variável ou tipo de dado; fclose - é usado para fechar um arquivo (fluxo) aberto pela função fopen() - um valor de retorno diferente de <zero> indica problemas no arquivo. feof - encontra final do arquivo - retorna verdadeiro (> zero) se o final do arquivo tiver sido encontrado, caso contrário retorna zero; 16.6 APAGANDO ARQUIVOS A função remove() apaga o arquivo especificado. Exemplo: remove("arqlivro.arq"); Professor: Ivo Mário Mathias 70