15 - Entrada/Saída
Trabalhando com arquivos
Nesta seção trabalharemos com as chamadas open, close, read e write.
Exercise 1
Resposta
Lê os 5 primeiros caracteres de um arquivo. O arquivo lido é passado via terminal.
Vamos agora usar o comando man para ver a documentação das chamadas de sistema do Linux. Digite no terminal man read. A tela mostrada contém a documentação da função read, incluindo sua assinatura e quais cabeçalhos devem ser incluídos para que ela possa ser usada.
Exercise 2
Resposta
A função read retorna o número de caracteres efetivamente lidos. Ela retorna 0 quando o arquivo acabou. A função só retorna quando os caracteres forem lidos, então ela pode bloquear o programa.
Tip 1
Para acelerar suas buscas no man você pode ativar a busca pressionando /. Aí basta digitar o termo procurado. Para avançar para as próximas ocorrências de um termo basta apertar / + Enter.
Example
Baseado em sua resposta acima, modifique exemplo_io1.c para que ele mostre o todo o conteúdo do arquivo.
Vamos agora trabalhar com a chamada write. Um exemplo de seu uso está mostrado no arquivo exemplo_io2.c.
Exercise 3
Resposta
write recebe o identificador do arquivo, um endereço de memória e o número de bytes que devem ser copiados deste endereço para o arquivo.
Example
Em um novo arquivo copy_file.c, crie um programa copy_file que recebe dois nomes de arquivos como argumentos no terminal e copia o conteúdo do primeiro para o segundo. Ou seja, você deverá
- abrir ambos arquivos (cada um terá seu próprio file descriptor)
- enquanto não chegar ao final do primeiro arquivo
- ler do primeiro para um buffer
- escrever este buffer no segundo
- fecha os dois arquivos
Validando 2
Após compilar, teste sua solução com um arquivo qualquer e utilize diff ou cmp para comparar os arquivos.
Extra
Estes exercícios não terão correção durante a aula e devem ser checados no atendimento. Faça-os se você já acabou os anteriores e a correção/discussão ainda não começou.
Até agora trabalhamos com um buffer com somente um caractere. Isso facilita a programação, mas deixa nosso código muito lento.
Example
Modifique o copy_file para usar um buffer de 100 caracteres. Meça o tempo de execução para a cópia de um arquivo grande (~100Mb) usando o comando time. Não se esqueça de verificar que os resultados ficaram iguais com o comando diff.
O comando time tem como saída três informações sobre o processo executado:
- Tempo Real (real): O tempo que real que levou para executar o comando, do início ao fim.
- Tempo do usuário (user): O tempo que a CPU gastou na tarefa em si.
- Tempo do sistema (sys): O tempo que a CPU gastou em tarefas de nível de sistema relacionadas ao comando.
Tip 3
Para saber mais como o time ou diff funcionam use o comando man conforme abaixo.
Tip 4
Você pode utilizar o comando dd para gerar um arquivo aleatório de tamanho arbitrário. Por exemplo, para gerar um arquivo de 100MB, podemos fazer:
Exercise 4
Resposta
Ter disponível o buffer aumentado faz com que o programa tenha que acessar menos vezes a fila de IO, provendo ganho de performance.
Permissões e posse de arquivos
No exemplo_io2.c passamos algumas opções extras para poder criar o arquivo:
A flag O_CREAT é usada para indicar que o arquivo deve ser criado caso ele não exista. O número 0700 representa os bits de acesso visto na expositiva. Cada dígito contém 3 dígitos que representam as seguintes permissões
- 4 - permissão de leitura
- 2 - permissão de escrita
- 1 - permissão de execução
O primeiro dígito contém as permissões do usuário dono do arquivo. O segundo dígito contém as permissões do grupo dono do arquivo. Usuários que pertencem a este grupo possuem estas permissões. O terceiro dígito lista as permissões para todos os outros usuários.
Exercise 5
Resposta
A primeira coluna contém as permissões na ordem leitura (r), escrita (w) e execução (x) para o dono do arquivo, o grupo principal do arquivo e todos os usuários. É usado o caractere - para as permissões não concedidas. A segunda coluna mostra o usuário dono do arquivo. A terceira mostra o grupo dono do arquivo.
Exercise 6
Resposta
Leitura e escrita para o dono, leitura para o grupo e nenhuma permissão para outros usuários. Ela é interessante pois permite edição somente pelo dono, mas permite leitura para alguns usuários que o dono confia. Porém, não permite que qualquer usuário leia nem escreva no arquivo.
Exercise 7
Resposta
755
Exercise 8
Resposta
Confira no output do ls -l. Se ainda restar dúvida, confira com o professor
Example
Use os comandos chown para mudar o dono do arquivo para seu usuário e chmod para deixar suas permissões como leitura e escrita para você e somente leitura para o restante.
Dica: não sabe como usar os comandos acima? Use man.
Extra
Estes exercícios trabalham com o conceito de posse de arquivos e de sobrescrita de arquivos já existentes.
Exercise 9
Resposta
Confira com o professor
Example
Conserte o erro ocorrido acima checando a saída de open. Consulte o manual caso necessário. Não se esqueça de fazê-lo para o arquivo fonte e destino.
Exercise 10
Resposta
Confira com o professor
Example
O copy_file sobrescreve arquivos sem considerar se arquivo existe ou não. Use o manual (man 2 open) para encontrar a flag que faz open falhar caso o arquivo de destino já exista e conserte seu programa para perguntar se o usuário deseja sobrescrever o arquivo. Entenda como usar errno para que você consiga diferenciar os dois tipos de erros.