Arquivos temporários em C

Ola, eu não esqueci de vocês não, apenas estou sem tempo com o final de semestre na faculdade. Então, para não deixar vazio, vamos mostrar como criar arquivos temporários em C.
Arquivos temporários são utilizados para uma vasta gama de utilidades, sendo que a mais comum é a comunicação entre processos. Isso mesmo, você leu direito, para dois processos se comunicarem é mais do que comum utilizarmos arquivos temporários. Isso quer dizer, por exemplo, que a maravilhosa função pipe() nada mais é do que uma criação de arquivos temporários.Com isso em vista, vamos utilizar a função mkstemp(), para criar um arquivo temporário, a função unlink() para remover o mesmo, e a clássica write()/read() para escrever no mesmo.
De acordo com o manual de mkstemp(), temos também as funções mktemp(), tempnam(), tmpnam() e tmpfile() para utilizarmos, porém somos instruídos a utilizar apenas mkstemp() e tmpfile(), já que as outras não são seguras, permitindo que ocorra uma “race condition“.
A diferença entre mkstemp() e tmpfile(), é basicamente que tmpfile() cria um arquivo temporário, dá o unlink() automaticamente e retorna um ponteiro para um FILE, já mkstemp() precisa receber um “template” como parâmetro (terminado com 6 X, ex: “/tmp/teste.XXXXXX”), e retorna um inteiro representando o arquivo temporário aberto, para podermos trabalhar com write()/read(). Honestamente, eu prefiro mkstemp(), mas isso é questão de gosto e costume ultimamente.
Agora que temos um background sobre o que utilizar e por que, vamos ao nosso código de exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>

int main(void){
char template[]=”/tmp/teste.XXXXXX”;
char tmp[200];
int tmpFd = -1;

memset(tmp,’\0′,sizeof(char)*200);

if((tmpFd=mkstemp(template))==-1){
perror(“mkstemp”);
return EXIT_FAILURE;
}

unlink(template);

if(write(tmpFd,”TESTE\n”,strlen(“TESTE\n”)) <= 0)
perror(“write”);

lseek(tmpFd,SEEK_SET,0);

if(read(tmpFd,&tmp,sizeof(char)*200) <= 0)
perror(“read”);

fprintf(stdout,”%s\n”,tmp);

close(tmpFd);

return EXIT_SUCCESS;
}

Ok, explicando o código passo a passo:

  1. Incluímos nossos headers
  2. Criamos nosso template (o manual de mkstemp() nos avisa para utilizarmos um ponteiro para uma variável, e não mkstemp(“/tmp/file.XXXXXX”);, já que ela irá criar o nome da variável temporária e atualizar o ponteiro com esse nome)
  3. Fazemos uma chamada à função mkstemp().
  4. Chamamos unlink() para removermos o arquivo quando dermos um close().
  5. Utilizamos write() para escrevermos no arquivo temporário (atenção, write() escreve n bytes e avança o ponteiro do arquivo esses mesmos n bytes, ou seja, nosso arquivo estará no final agora).
  6. Utilizamos lseek() para retornamos ao inicio do arquivo e podermos ler.
  7. Utilizamos read() para ler do arquivo.
  8. Mostramos o conteúdo do arquivo na tela.
  9. Fechamos (e removemos) o arquivo com close().

Normalmente, os programas que vão utilizar arquivos para comunicação entre processos, criam os arquivos logo no inicio do programa, e para as funções que vão escrever no mesmo, passam como parâmetro o “file descriptor” do mesmo, ou utilizam um “file descriptor” global (eu pessoalmente não gosto), dessa forma, se tivermos um programa que faça um fork(), podemos escrever e ler do mesmo arquivo, evitando “race conditions“, e criando a comunicação entre processos corretamente.
Espero que isso tenha ajudado a algumas pessoas com dúvidas nisso, lembrem, que é sempre bom utilizar arquivos temporários, no lugar de arquivos fixos fazendo o trabalho de arquivos temporários, dessa forma um programa possuirá um entendimento mais simples e coerente com o código.

About Zarnick

Programer, sysadmin, guitarrist, and Italian. That's what I am. Plain simple.
ANSI C, C/C++, News, Tips, Tutorials , , , , , , ,