As funções para trabalhar com ficheiros são fornecidas pelo módulo File.
Para leres um ficheiro inteiro, usa File.read/1. Para escreveres num ficheiro, usa File.write/2.
Sempre que escreves num ficheiro com File.write/2, é aberto um descritor de ficheiro e é criado um novo processo de Elixir. Por este motivo, deves evitar escrever num ficheiro dentro de um ciclo com File.write/2.
Em vez disso, podes abrir um ficheiro com File.open/2. O segundo argumento de File.open/2 é uma lista de modos, que te permite especificar se queres abrir o ficheiro para leitura ou para escrita.
File.open/2 devolve um PID de um processo que trata do ficheiro. Para leres e escreveres no ficheiro, usa funções do módulo IO e passa este PID como dispositivo de IO.
Quando terminares de trabalhar com o ficheiro, fecha-o com File.close/1.
Todas as funções mencionadas do módulo File têm também uma variante com ! que lança um erro em vez de devolver uma tupla de erro (por exemplo, File.read!/1). Usa essa variante se não tencionas tratar erros como ficheiros inexistentes ou falta de permissões.
És um grande entusiasta de comboios em miniatura e decidiste partilhar a tua paixão com o mundo ao criar uma newsletter. Vais começar por enviar o primeiro número da tua newsletter aos teus amigos e conhecidos que partilham este passatempo. Tens um ficheiro de texto com uma lista dos endereços de email deles.
Implementa a função Newsletter.read_emails/1. Deve receber um caminho de ficheiro. O ficheiro é um ficheiro de texto que contém endereços de email separados por mudanças de linha. A função deve devolver uma lista com os endereços de email do ficheiro.
Newsletter.read_emails("/home/my_user/documents/model_train_friends_emails.txt")
# => ["rick@example.com", "choochoo42@example.com", "anna@example.com"]
Enviar um email é uma tarefa que pode falhar por muitas razões imprevisíveis, como um erro de escrita no endereço de email ou problemas temporários de rede. Para garantires que consegues tentar novamente enviar os emails a todos os teus amigos sem enviar duplicados, precisas de registar os endereços de email que já receberam o email. Para isso, vais precisar de um ficheiro de registo.
Implementa a função Newsletter.open_log/1. Deve receber um caminho de ficheiro, abrir o ficheiro para escrita e devolver o PID do processo que trata do ficheiro.
Newsletter.open_log("/home/my_user/documents/newsletter_issue1_log.txt")
# => #PID<0.145.0>
Implementa a função Newsletter.log_sent_email/2. Deve receber o PID do processo que trata do ficheiro e uma string com o endereço de email. Deve escrever o endereço de email no ficheiro, seguido de uma mudança de linha.
Newsletter.log_sent_email(pid, "joe@example.com")
# => :ok
Implementa a função Newsletter.close_log/1. Deve receber o PID do processo que trata do ficheiro e fechar o ficheiro.
Newsletter.close_log(pid)
# => :ok
Agora que tens todos os blocos de construção do procedimento de envio de emails, precisas de os combinar numa única função.
Implementa a função Newsletter.send_newsletter/3. Deve receber o caminho do ficheiro com os endereços de email, o caminho de um ficheiro de registo e uma função anónima que envia um email para um determinado endereço de email. Deve ler todos os endereços de email do ficheiro indicado e tentar enviar um email a cada um deles. Se a função anónima que envia o email devolver :ok, escreve o endereço de email no ficheiro de registo, seguido de uma mudança de linha. Certifica-te de que o fazes logo que o email seja enviado. Depois de concluídos todos os envios, fecha o ficheiro de registo.
Newsletter.send_newsletter(
"model_train_friends_emails.txt",
"newsletter_issue1_log.txt",
fn email -> :ok end
)
# => :ok
Inscreve-te no Exercism para aprenderes e dominares Elixir com 58 conceitos168 exercícios, e mentoria humana real, tudo grátis.