Arquivos
INF01202
Prof. Lucas Mello Schnorr
Sumário
Lidar com Arquivos I Introdução I Conceitos I Terminologia
Em C (lidar com o conteúdo de arquivos) I Abrir fopen
I Fechar fclose I Ler fread I Escrever fwrite I Descarregar fflush I Testar m de arquivo feof I Avaliar condição de erro ferror
Arquivos
6 INF 01202 - Prof. Marcelo Walter – Aula 24
ü Repositóriospermanentes de dados
(informações) que possibilitam a comunicação dos programas com o ambiente.
ü Usualmente armazenados em dispositivos de memória auxiliar
(discos).
ü A alteração de um arquivo durante a execução de um programa torna
permanente - além do tempo de execução do programa - o processamento realizado.
ü Em arquivos é possível armazenar-se bem mais informações do que na memória principal.
Aula de Hoje - Arquivos
Cortesia: Prof. Marcelo Walter 3 / 22
Arquivos em C
7 INF 01202 - Prof. Marcelo Walter – Aula 24
Arquivos em C
ü Repositórios permanentes de streams – sequências de bytes - armazenados em dispositivos de memória auxiliar
de forma permanente, a partir do uso de periféricos que aceitam tanto a leitura como a gravação de dados (discos magnéticos, pen drives, etc).
ü Toda a entrada ou saída de dados é processada através do processamento de streams, independentemente do periférico utilizado (device independent)
ü As operações de entrada e saída de dados de um
arquivo (incluídos os dispositivos padrão stdin - de entrada e stdout - de saída) são apoiadas pelo armazenamento temporário destes streams em áreas da memória principal denominadas buffers.
Stream
Streams
• O sistema de E/S do C utiliza o conceito de streams.
• Um stream é um dispositivo lógico (um canal de manipulação) que representa um arquivo ou um dispositivo qualquer (monitor, teclado,etc). • Operações sobre streams são “bufferizadas”,
ou seja, trabalham com uma área de memória intermediária (buffer) e não propriamente sobre o disco.
4
Cortesia: Prof. Edison Pignaton de Freitas 5 / 22
Como funciona?
8 INF 01202 - Prof. Marcelo Walter – Aula 24
Esquema de utilização de arquivos
Abre/Cria Fecha e salva em DISCO Descarrega buffer Disco MANIPULA Memória principal Movimentação de dados Funções Arquivo x Buffer do arquivo x
• arquivo: entidade externa ao programa;
• armazenamento permanente (não se perdem ao término do programa) das informações em memória secundária (periféricos).
Tipos de arquivo
9 INF 01202 - Prof. Marcelo Walter – Aula 24
ü Binário: composto por uma sequência (fluxo binário) de
bytes lidos, sem tradução, diretamente do dispositivo externo. Não ocorre nenhuma tradução e existe uma correspondência um para um entre os dados do dispositivo e os que estão no fluxo.
Ø Texto: composto de uma sequência de bytes
correspondendo a uma sequência de caracteres ASCII, incluindo letras, dígitos e caracteres especiais utilizados na escrita e os separadores branco, tab e new line (indicando final de linha e, dependendo do ambiente, utilizando para isso 1 ou 2 caracteres ASCII ), que pode ou não ser dividida em linhas terminadas por um caractere de final de linha.
Tipos de arquivos do C
Nas próximas aulas Aula de Hoje
Cortesia: Prof. Marcelo Walter 7 / 22
Arquivo Binário
10 INF 01202 - Prof. Marcelo Walter – Aula 24
• agregado sequencial de bytes;
• logicamente, o stream pode ser visto
como um conjunto de dados simples ou estruturados;
• não tem limitação teórica de tamanho;
• comprimento do arquivo: número de
elementos que apresenta no momento; • elementos não tem nome;
• somente um elemento é acessível a cada
momento
→ elemento corrente
• Acesso aos dados: sequencial ou randômico.
Arquivo Binário
O que está armazenado aqui?
Exemplo de arquivo binário com inteiros
12 INF 01202 - Prof. Marcelo Walter – Aula 24
1 inteiro = 4 bytes
00000000000000000000000000000100 (...
) 00000000000000000000000000000001
Arquivos:
armazenamentoSeja um arquivo de inteiros :
Primeiro inteiro Último inteiro
As separações entre bytes são apenas ilustrativas, no disco não existem! 00000000000000000000000000100000
Segundo inteiro
fim de arquivo
Cortesia: Prof. Marcelo Walter 9 / 22
Operações em C para arquivos binários
Retiradas da biblioteca stdio.h
Operação Função Abrir fopen Fechar fclose Ler fread Escrever fwrite Descarregar fflush Testar m de arquivo feof Avaliar condição de erro ferror
Protótipos das funções
O que há de comum entre estas funções?
FILE *fopen(const char *pathname, const char *mode);
int fclose(FILE *stream);
size_t fread(void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
size_t fwrite(const void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
int fflush(FILE *stream);
int feof(FILE *stream);
O ponteiro para uma estrutura FILE (aka FILE*)
Slide 9 INF 01202
Declaração de um ponteiro “FILE”
FILE *point_arq
• O tipo FILE identifica um stream, contendo informação necessária para seu controle (como indicadores de posição de função).
// Programa que utiliza arquivos
#include <stdio.h>// e demais biblioteca necessárias ...
int main( ) {
FILE *arq; //declaração de um “ponteiro de arquivo”
FILE *arq1, *arq2; ...
}
Observar que FILE é
sempre escrito em maiúsculas!!!
Para cada arquivo utilizado
simultaneamente deve ter sido ou ser definido um ponteiro.
Sempre vericar o retorno destas funções
Slide 10 INF 01202
Funções de manipulação de arquivo
• fopen • fclose • fflush • fread • fwrite • feof • ferror O sucesso ou fracasso da execução destas funções pode ser verificado a partir do valor retornado. É altamente recomendado que os programas incluam
esta verificação!
Cortesia: Prof. Claudio Jung 13 / 22
Abrir arquivo fopen
FILE *fopen(const char *pathname, const char *mode); pathname é o caminho para o arquivo (o nome do arquivo) mode é o modo de abertura
Modo Comportamento stream
r para leitura início
r+ para leitura e escrita, não apaga arquivo início w para escrita, apaga arquivo se existe início w+ para leitura e escrita, o arquivo é truncado início a para concatenação no nal do arquivo m a+ para leitura e concatenação no nal do arquivo m
Pode-se misturar modos.
Outros modos relevantes: b para arquivos binários. Valor de retorno:
I se tudo bem, ponteiro para o descrito de arquivo subjacente I caso contrário, NULL
Abrir arquivo fopen
FILE *fopen(const char *pathname, const char *mode); pathname é o caminho para o arquivo (o nome do arquivo) mode é o modo de abertura
Modo Comportamento stream
r para leitura início
r+ para leitura e escrita, não apaga arquivo início w para escrita, apaga arquivo se existe início w+ para leitura e escrita, o arquivo é truncado início a para concatenação no nal do arquivo m a+ para leitura e concatenação no nal do arquivo m Pode-se misturar modos.
Outros modos relevantes: b para arquivos binários.
Valor de retorno:
I se tudo bem, ponteiro para o descrito de arquivo subjacente I caso contrário, NULL
Abrir arquivo fopen
FILE *fopen(const char *pathname, const char *mode); pathname é o caminho para o arquivo (o nome do arquivo) mode é o modo de abertura
Modo Comportamento stream
r para leitura início
r+ para leitura e escrita, não apaga arquivo início w para escrita, apaga arquivo se existe início w+ para leitura e escrita, o arquivo é truncado início a para concatenação no nal do arquivo m a+ para leitura e concatenação no nal do arquivo m Pode-se misturar modos.
Outros modos relevantes: b para arquivos binários. Valor de retorno:
I se tudo bem, ponteiro para o descrito de arquivo subjacente I caso contrário, NULL
Fechar arquivo fclose
Protótipo
int fclose(FILE *stream);
A função fclose descarrega o stream apontado por stream (escrevendo qualquer dado buferizado usando fflush) e fecha o descritor de arquivo subjacente.
Valor de retorno
I se tudo bem, 0 é retornado
I caso contrário, o valor de EOF é retornado.
Exemplo com fopen/fclose
#include <stdio.h>
int main() {
FILE *arquivo;
arquivo = fopen("notas_da_turma.bin", "r");
if (arquivo == NULL){
printf("O arquivo não pode ser aberto.\n"); }
return 0; }
Assumindo que o arquivo existe, o que aconteceria se: I O modo fosse "rb"
I O modo fosse "ra" I O modo fosse "a" I O modo fosse "w"
Exemplo com fopen/fclose
#include <stdio.h>
int main() {
FILE *arquivo;
arquivo = fopen("notas_da_turma.bin", "r");
if (arquivo == NULL){
printf("O arquivo não pode ser aberto.\n"); }
return 0; }
Assumindo que o arquivo existe, o que aconteceria se: I O modo fosse "rb"
I O modo fosse "ra" I O modo fosse "a" I O modo fosse "w"
A função de descarregamento fflush
Para streams de saída
I Força a escrita em disco de todos os dados em buer
Para streams de entrada
I Desconsidera todos os dados em buer que ainda não consumidos
Para o caso do exemplo abaixo
fflush(NULL);
A função de descarregamento fflush
Para streams de saída
I Força a escrita em disco de todos os dados em buer Para streams de entrada
I Desconsidera todos os dados em buer que ainda não consumidos
Para o caso do exemplo abaixo
fflush(NULL);
a função descarrega todos os streams de saída abertos.
A função de descarregamento fflush
Para streams de saída
I Força a escrita em disco de todos os dados em buer Para streams de entrada
I Desconsidera todos os dados em buer que ainda não consumidos
Para o caso do exemplo abaixo
fflush(NULL);
Escrever fwrite
Protótipo
size_t fwrite(const void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
Escreve nmemb itens de dados, cada um de tamanho size bytes, para o stream apontado por stream, obtendo os dados da localização dada pelo endereço em ptr.
Exemplos
int meu_inteiro;
fwrite(&meu_inteiro, sizeof(int), 1, arquivo);
double muitos_dados[TAMANHO];
fwrite(&muitos_dados, sizeof(double), TAMANHO, arquivo);
Escrever fwrite
Protótipo
size_t fwrite(const void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
Escreve nmemb itens de dados, cada um de tamanho size bytes, para o stream apontado por stream, obtendo os dados da localização dada pelo endereço em ptr.
Exemplos
int meu_inteiro;
fwrite(&meu_inteiro, sizeof(int), 1, arquivo);
double muitos_dados[TAMANHO];
Ler fread
Protótipo
size_t fread(void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
Lê nmemb itens de dados, cada um de tamanho size bytes, do stream apontado por stream, registrando os dados lidos na localização dada pelo endereço em ptr.
Exemplos
int meu_inteiro;
fread(&meu_inteiro, sizeof(int), 1, arquivo);
double muitos_dados[TAMANHO];
fread(&muitos_dados, sizeof(double), TAMANHO, arquivo);
Ler fread
Protótipo
size_t fread(void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
Lê nmemb itens de dados, cada um de tamanho size bytes, do stream apontado por stream, registrando os dados lidos na localização dada pelo endereço em ptr.
Exemplos
int meu_inteiro;
fread(&meu_inteiro, sizeof(int), 1, arquivo);
double muitos_dados[TAMANHO];
Valor de retorno de fwrite e fread
Protótipos
size_t fwrite(const void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
size_t fread(void *ptr,
size_t size,
size_t nmemb,
FILE *stream);
As duas funções retornam a quantidade de bytes efetivamente escritos ou lidos.
Testar EOF com feof e condição de erro com fwrite
int feof(FILE *stream);
int ferror(FILE *stream);
A função feof testa o indicador de m de arquivo para o stream apontado por stream, retornando não zero se estiver setado.
A função ferror testa o indicador de erro para o stream apontado por stream, retornando não zero se estiver setado.
Estas funções podem (ou até devem) ser empregadas após cada operação de entrada/saída.
Exemplo: ler enquanto não chegar no m do arquivo
while(!feof(arquivo)) { ... }
Exemplo: vericar se houveram erros na leitura
int meu_inteiro;
fread(&meu_inteiro, sizeof(int), 1, arquivo);
if (ferror(arquivo)) {
// aconteceu um erro na leitura
Testar EOF com feof e condição de erro com fwrite
int feof(FILE *stream);
int ferror(FILE *stream);
A função feof testa o indicador de m de arquivo para o stream apontado por stream, retornando não zero se estiver setado.
A função ferror testa o indicador de erro para o stream apontado por stream, retornando não zero se estiver setado.
Estas funções podem (ou até devem) ser empregadas após cada operação de entrada/saída.
Exemplo: ler enquanto não chegar no m do arquivo
while(!feof(arquivo)) { ... }
Exemplo: vericar se houveram erros na leitura
int meu_inteiro;
fread(&meu_inteiro, sizeof(int), 1, arquivo);
if (ferror(arquivo)) {
// aconteceu um erro na leitura
}
Testar EOF com feof e condição de erro com fwrite
int feof(FILE *stream);
int ferror(FILE *stream);
A função feof testa o indicador de m de arquivo para o stream apontado por stream, retornando não zero se estiver setado.
A função ferror testa o indicador de erro para o stream apontado por stream, retornando não zero se estiver setado.
Estas funções podem (ou até devem) ser empregadas após cada operação de entrada/saída.
Exemplo: ler enquanto não chegar no m do arquivo
while(!feof(arquivo)) { ... }
Exemplo: vericar se houveram erros na leitura
int meu_inteiro;
fread(&meu_inteiro, sizeof(int), 1, arquivo);
if (ferror(arquivo)) {
// aconteceu um erro na leitura
Exercício #1
Slide 26 INF 01202
26
Exercícios
1. Faça um programa para gravar um arquivo composto por estruturas que contenham nome, idade e altura de atletas.
2. Faça outro programa, agora para listar um arquivo com estas estruturas.
3. Faça uma função (que recebe um nome de arquivo como entrada), e imprima a altura de atletas cujos nomes foram lidos do teclado. A função deve abrir e fechar o arquivo, e possibilitar a busca de diversos atletas.
4. Faça outro programa que insere um novo registro no final do arquivo.
Cortesia: Prof. Claudio Jung 22 / 22