Функції для роботи з файлами надає модуль File.
Щоб прочитати файл повністю, використаймо File.read/1. Щоб записати у файл, використаймо File.write/2.
Щоразу, коли ми записуємо у файл за допомогою File.write/2, відкривається дескриптор файлу і створюється новий процес Elixir. Тому запису у файл у циклі за допомогою File.write/2 варто уникати.
Замість цього файл можна відкрити за допомогою File.open/2. Другим аргументом File.open/2 є список режимів, який дає змогу вказати, чи відкриваємо ми файл для читання чи для запису.
File.open/2 повертає PID процесу, який обробляє файл. Щоб читати з файлу й записувати до нього, скористаймося функціями з модуля IO і передамо цей PID як пристрій вводу-виводу.
Коли ми завершимо роботу з файлом, закриймо його за допомогою File.close/1.
Усі згадані функції з модуля File також мають варіант із !, який спричиняє помилку замість повернення кортежу помилки (наприклад, File.read!/1). Скористаймося цим варіантом, якщо ми не збираємося обробляти такі помилки, як відсутній файл або брак дозволів.
Ми великі поціновувачі моделей потягів і вирішили поділитися своїм захопленням зі світом, започаткувавши розсилку новин. Почнімо з того, що надішлемо перший випуск нашої розсилки друзям і знайомим, які поділяють наше захоплення. У нас є текстовий файл зі списком їхніх адрес електронної пошти.
Реалізуйте функцію Newsletter.read_emails/1. Вона має приймати шлях до файлу. Це текстовий файл, що містить адреси електронної пошти, розділені символами нового рядка. Функція має повернути масив адрес електронної пошти з файлу.
Newsletter.read_emails("/home/my_user/documents/model_train_friends_emails.txt")
# => ["rick@example.com", "choochoo42@example.com", "anna@example.com"]
Надсилання електронного листа може не вдатися з багатьох непередбачуваних причин, як-от одруківка в адресі електронної пошти чи тимчасові проблеми з мережею. Щоб мати змогу повторити надсилання листів усім друзям і не надіслати дублікатів, потрібно записувати в журнал адреси, які вже отримали лист. Для цього знадобиться файл журналу.
Реалізуйте функцію Newsletter.open_log/1. Вона має приймати шлях до файлу, відкривати файл для запису й повертати PID процесу, який обслуговує цей файл.
Newsletter.open_log("/home/my_user/documents/newsletter_issue1_log.txt")
# => #PID<0.145.0>
Реалізуйте функцію Newsletter.log_sent_email/2. Вона має приймати PID процесу, який обслуговує файл, і рядок тексту (англ. string) з адресою електронної пошти. Вона має записати адресу електронної пошти у файл, додавши після неї символ нового рядка.
Newsletter.log_sent_email(pid, "joe@example.com")
# => :ok
Реалізуйте функцію Newsletter.close_log/1. Вона має приймати PID процесу, який обслуговує файл, і закривати файл.
Newsletter.close_log(pid)
# => :ok
Тепер, коли в нас є всі складники процедури надсилання листів, потрібно поєднати їх в одній функції.
Реалізуйте функцію Newsletter.send_newsletter/3. Вона має приймати шлях до файлу з адресами електронної пошти, шлях до файлу журналу й анонімну функцію, яка надсилає лист на вказану адресу електронної пошти. Вона має прочитати всі адреси електронної пошти з указаного файлу й спробувати надіслати лист на кожну з них. Якщо анонімна функція, яка надсилає лист, повертає :ok, запишіть адресу електронної пошти у файл журналу, додавши після неї символ нового рядка. Обовʼязково зробіть це одразу після надсилання листа. Коли всі листи надіслано, закрийте файл журналу.
Newsletter.send_newsletter(
"model_train_friends_emails.txt",
"newsletter_issue1_log.txt",
fn email -> :ok end
)
# => :ok
Зареєструйтеся на Exercism, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.