Você está na página 1de 33

Arquivos na Linguagem C

Praticamente todas as aplicaes necessitam


armazenar ou ler dados de arquivos de dados
A linguagem C oferece 2 formas bsicas de
manipulao com arquivos
E/S de alto nvel
Bufferizao interna
Uso de STREAMS
Utiliza apontadores para arquivos: FILE *

E/S de baixo nvel


Utiliza chamadas semelhantes s System Calls do UNIX
Bufferizao externa, fornecida pelo programador
Manipula diretamente os descritores de arquivos do Sistema
Operacional

Arquivos na Linguagem C

STREAMS
Streams so fluxos de dados armazenados em buffers de
memria interna e associados a arquivos em dispositivos
externos
Na linguagem C um stream est associado a um tipo de
dado denominado FILE * e pode ser denominado de
apontador de arquivos
A E/S de alto nvel utiliza streams
A conexo de um arquivo a um stream feita abrindo o
arquivo. A conexo termina quando o mesmo fechado.

O tratamento de arquivos de alto-nvel em C faz uso


do tipo de dados FILE que est definido em stdio.h

E/S de Alto Nvel

No Turbo C a definio de FILE a seguinte:


typedef struct {
int level;
/* fill/empty level of buffer */
unsigned flags;
/* File status flags */
char fd;
/* File descriptor */
unsigned char hold; /* Ungetc char */
int bsize;
/* Buffer size */
unsigned char *buffer;/* Data buffer */
unsigned char *curp; /* Current pointer */
unsigned istemp;
/* Temporary file */
short token;
/* Validity checking */
} FILE;

E/S de Alto Nvel


O programador no precisa conhecer nem se preocupar com
o contedo do tipo FILE.
Precisa apenas utiliz-lo nas chamadas s funes de
manipulao de arquivos de alto nvel.
As principais funes so:
fopen( ), fclose( ), putc( ), getc( ), fseek( ), fflush( ),
fprintf( ), fscanf( ), fputs( ), fgets( ), ferror( ).

Quando um programa inicia sua execuo 3 streams


so abertos automaticamente
stdin (associado entrada padro)
stdout (associado sada padro)
stderr (associado sada padro de erros)

E/S de Alto Nvel


Os nomes destes streams esto associados a constantes
simblicas e podem ser usados em quaisquer operaes
onde se use apontadores de arquivos, mas no podem ser
alterados

Abertura de arquivos - fopen()


fopen() abre o arquivo indicado e retorna um stream, ou
NULL se houver um erro
#include <stdio.h>
FILE *fopen(const char *nome, const char *modo)
"r" - abre um arquivo texto para leitura.
"w" - cria um arquivo texto para gravao;
elimina o contedo anterior se houver.

E/S de Alto Nvel


"a"

- abre ou cria um arquivo de texto para


gravao no final do arquivo
"r+" - abre arquivo de texto para atualizao;
o contedo anterior mantido inalterado.
"w+" - cria arquivo de texto para atualizao;
elimina o contedo anterior se houver.
"a+" - abre ou cria um arquivo de texto para
atualizao no final do arquivo.
fundamental testar o retorno de fopen( ) para garantir que
o arquivo foi aberto com sucesso.
Se o modo incluir um b em seu final ("wb", "r+b") significa
que o arquivo tratado como binrio, e as converses \n
para CR+LF no sero realizadas

E/S de Alto Nvel

Exemplo com fopen()


#include <stdio.h>
main()
{
FILE *fp;
if ((fp = fopen("teste", "w")) == NULL) {
perror("teste");
return (1);
}
/* Faz uso do arquivo */
}

E/S de Alto Nvel

Fechando arquivos - fclose()


fclose() grava no disco qualquer dado pendente no
buffer interno, libera qualquer rea de memria alocada
dinamicamente para o stream e fecha o arquivo associado.
Retorna EOF se houve um erro e zero caso contrrio.
#include <stdio.h>
int fclose(FILE *stream);
Em C todos os arquivos abertos so fechados quando a
aplicao termina de forma normal, mas importante
fechar arquivos que no estejam mais sendo utilizados,
pois h um limite para o nmero de arquivos abertos por
aplicao.

E/S de Alto Nvel

Exemplo com fclose()


#include <stdio.h>
main()
{
FILE *fp;
if ((fp = fopen("teste", "w")) == NULL) {
perror("teste");
return (1);
}
/* Faz uso do arquivo */
fclose(fp);
}

E/S de Alto Nvel

Lendo caracteres - getc() e fgetc()


getc() e fgetc() so funcionalmente equivalentes e lem
o prximo caracter do stream passado como parmetro.
Devolvem EOF em caso de erro. A diferena que getc()
pode ser uma macro.
#include <stdio.h>
int getc(FILE *stream);
int fgetc(FILE *stream);

Escrevendo caracteres - putc() e fputc()


putc() e fputc() so funcionalmente equivalentes e
escrevem um caracter no stream passado como parmetro.
Retornam o caracter escrito com sucesso ou EOF em caso
de falha. A diferena que putc() pode ser uma macro.

E/S de Alto Nvel


#include <stdio.h>
int putc(int c, FILE *stream);
int fputc(int c, FILE *stream);
Vale observar que embora estas funes recebam caracter
a caracter, as operaes com o disco no so realizadas
desta forma, uma vez que estas so bufferizadas, o que as
torna mais rpidas.
As rotinas getchar() e putchar() vistas anteriormente
so implementadas com base em getc() e putc(),
respectivamente:
#define getchar() getc(stdin)
#define putchar(c) putc((c), stdout)

Exemplo: Utilitrio cat do UNIX


#include <stdio.h>
void copia_arq(FILE *fp_in, FILE *fp_out);
main(int argc, char *argv[])
{
FILE *fp;
if (argc == 1) {
/* Nenhum argumento. Copia stdin */
copia_arq(stdin, stdout);
} else {
while (--argc > 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
perror(*argv);
return (1);
} else {

Exemplo: Utilitrio cat do UNIX


copia_arq(fp, stdout);
fclose(fp);
}
}
return (0);
}
void copia_arq(FILE *fp_in, FILE *fp_out)
{
int c;
while ((c = getc(fp_in)) != EOF) {
putc(c, fp_out);
}
}

E/S de Alto Nvel

Devolvendo caracteres - ungetc()


ungetc() devolve um caracter de volta no stream. S
garantida a devoluo de um nico caractere. EOF no
pode ser devolvido.
ungetc() retorna o caracter devolvido em caso de
sucesso e EOF em caso de falha.
#include <stdio.h>
int ungetc(int c, FILE *stream);

Escrevendo e Lendo Cadeias


fputs() escreve uma cadeia no arquivo e a segue por um
new-line (\n). Retorna EOF em caso de falha ou um valor
no negativo em caso de sucesso.

E/S de Alto Nvel


#include <stdio.h>
int fputs(const char *s, FILE *stream);

fgets() l uma cadeia de caracteres de um stream.


Recebe um parmetro que especifica o tamanho mximo
da cadeia a ser lida. A leitura pra se for encontrado um \n.
Retorna a cadeia lida em caso de sucesso ou NULL em
caso de erro.
#include <stdio.h>
char *fgets(char *s, int n, FILE *stream);

E/S de Alto Nvel

Entrada/Sada formatada
fscanf() semelhante a scanf(), s que recebe um
parmetro a mais indicando o stream de onde devem ser
lidos os dados.
#include <stdio.h>
int fscanf(FILE *fp, const char *formato, ...);
scanf(...) fscanf(stdin, ...)

fprintf() semelhante a printf(), s que recebe um


parmetro a mais indicando o stream onde devem ser
escritos os dados.
#include <stdio.h>
int fprintf(FILE *fp, const char *formato, ...);
printf(...) fprintf(stdout, ...)

E/S de Alto Nvel

Leitura/Escrita Direta
fread() l de um stream um conjunto de objetos de um
tamanho especificado, armazenando-os em um vetor de
dados. Retorna o nmero de objetos realmente lidos.

#include <stdio.h>
size_t fread(void *buf, size_t tamanho,
size_t quantidade, FILE *stream);
fwrite() escreve num stream um conjunto de objetos de
um tamanho especificado. Os objetos a serem armazenados
devem estar em um vetor de dados. fwrite() retorna o
nmero de objetos realmente escritos.

E/S de Alto Nvel


#include <stdio.h>
size_t fwrite(const void *buf, size_t tamanho,
size_t quantidade, FILE *stream);

Descarregando o contedo do buffer


fflush() sobre um stream de sada, grava no arquivo
associado quaisquer dados armazenados no buffer e ainda
no escritos em disco.
#include <stdio.h>
int fflush(FILE *fp);
fflush() retorna zero no caso de sucesso e EOF em
caso de falha.

E/S de Alto Nvel

Manipulando a posio de arquivo


fseek() estabelece a posio atual do arquivo (em bytes)
para o stream indicado. Retorna zero em caso de sucesso
e um valor diferente de zero em caso de erro.
#include <stdio.h>
int fseek(FILE *fp, long desloc, int origem);
a posio estabelecida pelo deslocamento de desloc
bytes a partir de origem, que pode assumir os seguintes
valores:
SEEK_SET - Incio do arquivo
SEEK_CUR - posio atual do arquivo
SEEK_END - final do arquivo

E/S de Alto Nvel


rewind() desloca a posio atual de arquivo para o incio
do mesmo.
#include <stdio.h>
void rewind(FILE *stream);
rewind(fp) fseek(fp, 0L, SEEK_SET)

ftell() retorna a posio atual do arquivo associado ao


stream, ou -1L em caso de erro.
#include <stdio.h>
long ftell(FILE *stream);

E/S de Alto Nvel

Manipulando erros
ferror() retorna um valor diferente de zero se o indicador
de erro para o stream indicado estiver setado.
#include <stdio.h>
int ferror(FILE *stream);
Varivel errno definida em <errno.h> contm o cdigo do
ltimo erro ocorrido.
feof() retorna um valor diferente de zero se o indicador
fim de arquivo para o stream indicado estiver setado.
#include <stdio.h>
int feof(FILE *stream);

E/S de Alto Nvel

Manipulando erros
clearerr() apaga os indicadores de erro e fim de arquivo
para o stream especificado.
#include <stdio.h>
void clearerr(FILE *stream);
perror() imprime na sada padro de erros a string
passada como parmetro seguida de dois pontos (:) e uma
mensagem associada a o ltimo erro ocorrido.
#include <stdio.h>
void perror(const char *s);

perror(s) fprintf(stderr, "%s: %s\n", s,


sys_errlist[errno])

E/S de Alto Nvel

Outras operaes com arquivos


remove() elimina do disco o arquivo cujo nome passado
como parmetro. Retorna valor no zero em caso de falha.
#include <stdio.h>
int remove(const char *nomearq);

rename() modifica o nome de um arquivo. Retorna zero


em caso de sucesso e um valor no zero em caso de falha.
#include <stdio.h>
int rename(const char *nome_ant,
const char *nome_novo);

E/S de Alto Nvel

Arquivos temporrios
tmpfile() cria um arquivo temporrio no modo "w+b",
este arquivo ser removido automaticamente quando for
fechado. Retorna um stream vlido em caso de sucesso e
NULL em caso de falha.
#include <stdio.h>
FILE *tmpfile(void);
tmpnam() devolve um nome de arquivo temporrio no
existente no diretrio corrente. Recebe um apontador para
o vetor que ir armazenar o nome ou NULL, caso em que
devolvido o endereo de um vetor esttico interno.
#include <stdio.h>
char *tmpnam(char *strnome);

E/S de Baixo Nvel

Descritores de Arquivos
Descritores de arquivos so nmeros inteiros que identificam
um arquivo junto ao sistema operacional.
So devolvidos pelas rotinas de E/S de baixo nvel que abrem
ou criam um arquivo
So utilizados como um parmetro em todas as rotinas de
E/S de baixo nvel que fazem a manipulao com o arquivos
Toda aplicao em C j recebe trs arquivos abertos, que
tm os seguintes descritores:
0 (associado entrada padro)
1 (associado sada padro)
2 (associado sada padro de erros)

E/S de Baixo Nvel

Abertura de arquivos: open()


open() abre o arquivo indicado e retorna um descritor de
arquivo vlido, ou -1 se houver um erro
#include <fcntl.h>
int open(char *nome, int modo, int perms)

nome - nome do arquivo (incluindo path) a abrir.


modo - indica como o arquivo deve ser aberto:
O_RDONLY - s leitura
O_WRONLY - s escrita
O_RDWR - leitura/escrita O_CREAT - cria arquivo
perms - octal c/ permisses de acesso ao arquivo

E/S de Baixo Nvel


int fd;
fd = open("teste", O_RDWR | O_CREAT, 0644);

Abre arquivo para realizar leitura/escrita. Se o arquivo no existir o


mesmo ser criado com as permisses rw-r--r-

Criao de arquivos: creat()


creat() cria o arquivo indicado contendo as permisses de
acesso estabelecidas. Retorna um descritor de arquivo vlido,
ou -1 se houver um erro
#include <io.h>
int creat(char *nome, int perms)
nome - nome do arquivo (incluindo path) a criar
perms - octal c/ permisses de acesso ao arquivo
no formato rwxrwxrwx

E/S de Baixo Nvel


int fd;
fd = creat("teste", 0755);

Cria arquivo com as permisses rwxr-xr-x

Fechando arquivos: close()


close() fecha um arquivo anteriormente aberto com open()
ou creat(). Devolve -1 em caso de erro.
#include <io.h>
int close(int fd);

E/S de Baixo Nvel

Escrevendo Dados: write()


write() escreve n bytes no arquivo indicado pelo descritor
de arquivo a partir do buffer especificado. Em caso de sucesso
devolve o total de bytes escritos, e -1 em caso de erro.
#include <io.h>
int write(int fd, void *buf, unsigned tam);

Lendo Dados: read()


read() l at n bytes do arquivo indicado pelo descritor de
arquivo escrevendo os dados lidos no buffer especificado. Em
caso de sucesso devolve o total de bytes realmente lidos, e -1
em caso de erro.
#include <io.h>
int read(int fd, void *buf, unsigned tam);

cp com rotinas de baixo nvel


#include <io.h>
#include <fcntl.h>
#include <stdio.h>
main(int argc, char *argv[])
{
int fd1, fd2, n;
char buf[BUFSIZ];
if (argc != 3) {
fprintf(stderr, "Argumentos invalidos.\n");
fprintf(stderr, "Formato correto:\n");
fprintf(stderr, "\tcp <arq1> <arq2>\n");
exit(1);
}

cp com rotinas de baixo nvel


if ((fd1 = open(*++argv, O_RDONLY, 0)) == -1 ||
(fd2 = creat(*++argv, 0666)) == -1) {
perror(*argv);
exit(2);
}
while ((n = read(fd1, buf, sizeof(buf)) > 0) {
if (write(fd2, buf, n) != n) {
fprintf(stderr,"cp: erro ao gravar %s\n", *argv);

exit(3);
}
}
close(fd1);
close(fd2);
return (0);
}

E/S de Baixo Nvel

Alterando a posio de arquivos: lseek()


lseek() fora a posio atual de um arquivo para um valor
resultante da unio do desloca-mento em bytes e a origem.
Retorna o deslocamento da nova posio atual em relao ao
inicio do arquivo e o valor -1 em caso de erro.

#include <io.h>
long lseek(int fd, long desloc, int origem);
os valores de origem, so os mesmos usados em fseek:
SEEK_SET - Incio do arquivo
SEEK_CUR - posio atual do arquivo
SEEK_END - final do arquivo

E/S de Baixo Nvel

Obtendo a posio atual: tell()


tell() devolve a posio atual do arquivo, como um
deslocamento em bytes em relao ao incio do arquivo. Em
caso de erro devolve -1.
#include <io.h>
long tell(int fd);

Eliminando arquivos: unlink()


unlink() elimina o arquivo cujo nome foi passado como
parmetro. No sucesso devolve 0 e em caso de erro -1.
#include <io.h>
int unlink(char *nomearq);