MC102 |
ARQUIVOS DE ACESSO SEQÜENCIAL |
Até agora, todos os dados lidos por nossos programas vinham do teclado, e todas as saídas íam para a tela.
Mas, e se quiséssemos guardar alguns resultados para reaproveitar mais tarde? Como faríamos? Simples, basta guardarmso esses dados em arquivos no computador.
Quando digitamos um texto, para guardá-lo, não salvamos em um arquivo? E quando queremos usar esse texto novamente não lemos o que salvamos anteriormente no arquivo? O princípio é o mesmo. Então, como usamos arquivos em Pascal?
Antes de mais nada, devemos declarar uma variável de arquivo. Como fazemos isso?
VAR nome_da_variável : FILE OF tipo_do_dado; |
Assim, para definirmos uma variável de arquivo, temos que saber o tipo de dado que colocaremos lá. Então, suponha que nosso arquivo é texte, então teremos:
VAR arq : FILE OF char; |
Mas, afinal, para que precisamos de uma variável de arquivo? Mais adiante veremos que é através dela que teremos acesso a nosso arquivo.
Esse tipo de arquivo texto já é pré-definido no pascal, ou seja, o Pascal tem um tipo pré-definido para arquivos texto: o text. Então, as duas declarações abaixo são equivalentes
VAR arq : FILE OF char; VAR arq : text; |
pois o pascal já fez essa declaração para você:
TYPE text = FILE OF char; |
Naturalmente, se você quiser arquivos de algum outro tipo que não char, você deve fazer, por exemplo:
VAR arq1 : FILE OF integer; arq2 : FILE OF real; etc |
só que, nesse caso, os arquivos são tratados de modo um pouco diferente pelo Pascal. Confira a lição de arquivos de acesso aleatório para ver como o Pascal trata esses arquivos.
Nesse momento, trataremos somente de arquivos texto.
Bom, agora já sabemos como declarar uma variável de arquivo. Agora, como a usamos?
Antes de querer lidar com o arquivo, precisaremos associar essa variável a um arquivo real no disco. Ou seja, precisamos associá-la ao nome de um arquivo que queiramos criar ou ao nome de um já existente que queiramos abrir. Como fazemos isso?
Assign(variável_de_arquivo, nome_do_arquivo); |
Por exemplo, o programa:
VAR arq : text; BEGIN Assign(arq,'oba.txt'); END. |
associa à variável "arq" o arquivo de nome "oba.txt". Lembre-se que tal arquivo não necessariamente precisa existir no disco.
Após associar o nome ao arquivo, qual o próximo passo? Aí depende: queremos criar um novo arquivo ou abrir um existente?
Suponha que queremos criar um arquivo novo:
VAR arq : text; BEGIN Assign(arq,'oba.txt'); Rewrite(arq); END. |
Pronto! O comando Rewrite cria um novo arquivo e o abre para gravação (escrita). E se o arquivo "oba.txt" já existir no disco? Nesse caso o Rewrite o apaga, escrevendo o novo conteúdo por cima dele. Ou seja, cuidado! Pois se o arquivo a ser criado já existir no disco, tudo que havia nele antes do Rewrite será perdido. Assim, a forma geral do Rewrite é:
Rewrite(variável_de_arquivo); |
Agora que criamos o arquivo, como fazemos para guardar algo nele? Como fazemos para escrever nele? De um modo bem semelhante a como escrevíamos na tela:
VAR arq : text; BEGIN Assign(arq,'oba.txt'); Rewrite(arq); write(arq, 'mensagem'); writeln(arq, 'para'); write(arq,'o arquivo') END. |
Isso irá gravar
mensagempara o arquivo |
no arquivo. Ou seja, do mesmo modo que o write e o writeln agem na tela, agem no arquivo.
O write e o writeln também podem ser usados para escrever outros tipos de dados. Eles convertem automanticamente os valores de dados numéricos para strings de dígitos antes de armazenar no arquivo texto. Assim, posso escrever:
VAR arq : text; idade : integer; str : string; BEGIN Assign(arq,'oba.txt'); Rewrite(arq); idade := 25; writeln(arq,'João',idade); str := 'Pedro Souza'; idade := 12; writeln(arq,str,idade) END. |
E se, em vez de cirarmos um arquivo, quisermos escrever em um já existente, sem apagar o conteúdo prévio deste? Neste caso, em vez de Rewrite usamos Append:
VAR arq : text; idade : integer; str : string; BEGIN Assign(arq,'oba.txt'); Append(arq); idade := 25; writeln(arq,'Jnova linha') END. |
Nesse exemplo, se o arquivo continha:
linha 1 escrevo linha 2 |
agora terá:
linha 1 escrevo linha 2 nova linha |
se "escrevo linha 2" foi gravada com writeln, ou:
linha 1 escrevo linha 2nova linha |
se "escrevo linha 2" foi gravada com write.
Assim, Append abre um arquivo já existente, de modo que possamos adicionar texto ao FINAL deste. Note que só adiciono ao fim do arquivo.
A forma geral do comando é:
Append(variável_de_arquivo); |
Como o Append assume que o arquivo existe, se este não existir, um erro em tempo de execução será gerado.
Agora, digamos que queremos apenas ler o conteúdo de um arquivo que está no disco, como fazemos? Com Reset:
Reset(variável_de_arquivo); |
Por exemplo, o seguinte programa
VAR arq : text; s : string[5]; s1 : string; BEGIN Assign(arq,'oba.txt'); Reset(arq); read(arq,s); readln(arq,s1); END. |
lê 2 strings de "oba.txt". O read lê até o tamanho máximo de s (5). Já o readln lê uma linha inteira do arquivo, armazenando-a em s1 (lê a linha ou até 255 caracteres, que é o máximo de string). Assim, se o arquivo contiver
este texto é grande eu o escrevi |
s terá "este " (repare que o espaço foi junto) e s1 terá o resto da linha, ou seja, "texto é grande".
Então, Reset abre um arquivo existente somente para leitura.
da mesma forma que o write, o read pode transformar o texto lido em valores numéricos. Por exemplo, lembra nosso arquivo anterior onde gravamos "João 25"? Como lemos isso?
VAR arq : text; s : string; id : integer; BEGIN Assign(arq,'oba.txt'); Reset(arq); readln(arq,s,id); END. |
Aqui, s terá "João" e id terá 25.
assim, tanto real quanto integer podem ser lidos, lembrando que, em um arquivo texto, quando lemos várias variáveis, como no exemplo acima, os caracteres delimitadores são os espaços, tabulação e CR (enter).
Se tentarmos ler uma seqüência não numérica com read e guardarmos em uma variável numérica, um erro ocorre (da mesma forma como quando recebemos do teclado).
Assim, é melhor escrever informações diferentes em linhas diferentes, ou seja, se estou guardando nomes e idades, gravo numa linha o nome e na outra a idade. É bem verdade que precisarei de dois writeln para gravar e dois readln para ler, mas fica mais organizado.
Suponha, então, que temos um arquivo chamado "idades.txt" com nomes e diades:
Rolando Caio da Rocha 23 Jacinto Dores 12 Armando Machado 34 |
Como fazemos para imprimir na tela o conteúdo desse arquivo?
VAR arq : text; s : string; id : integer; BEGIN Assign(arq,'oba.txt'); Reset(arq); WHILE NOT eof(arq) DO BEGIN readln(arq,s); readln(arq,id); writeln(s,' - ',id) END END. |
O que eof faz? Sua sintaxe é:
Eof(variável_de_arquivo) : boolean; |
e ele retorna True se o arquivo chegou ao fim (EOF = End Of File). É útil quando não sabemos quantas linhas tem o arquivo.