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.