Наш чатик

Телеграм чат начинающих программистов. Общаемся и помогаем друг другу

Если ссылка не открывается, можно найти нас в поиске по чатам @rubyrush или пойти другим путем

Запись файлов в Ruby

Сегодня мы научимся писать данные в файлы, узнаем как работать со временем в Ruby, напишем программу-дневник.

План урока

  1. Как работать со временем в Ruby
  2. Запись в файлы, пишем дневник

Работаем со временем — класс Time

В Ruby есть класс для удобной работы со временем. Он называется Time. Например, чтобы понять, который сейчас час гики-программисты не смотрят на часы, а просто быстренько пишут программу на Ruby, в которой пишут одну строчку

puts Time.now

Дело в том, что метод now (англ. «сейчас») класса Time возвращает текущий момент времени:

2014-11-24 17:52:13 +0300

Любой экземпляр класса Time — объект «момента времени». Именно такой объект возвращает метод Time.now.

У экземпляра класса Time есть много полезных методов. Но самый важный из них — метод strftime, который возвращает время в виде строки по специальному шаблону, например

time = Time.now
puts time.strftime("%H:%M")

Выведет на экран текущее время в 24-часовом формате с точностью до минут:

17:55

Чтобы попросить метод strftime вывести время именно в таком формате, мы передаём ему в качестве параметра так называемый «формат времени», строчку "%H:%M".

Вот эти вот конструкции %H и %M (специальные ключи) метод заменяет на соответствующие данные из объекта класса Time, у которого он был вызван.

  • %H — часы в 24-часовом формате
  • %M — минуты с нулём, если меньше 10

А остальные символы (всё, что не начинается с %, в нашем случае двоеточие), остаются как и были.

Чтобы вывести, например, текущую дату, нужно написать:

puts time.strftime("%d.%m.%Y")

Это выведет что-то типа:

24.11.2014

Это, кстати, не только в Ruby. Такой способ форматирования времени с помощью специальных шаблонов-строк — некий общепринятый в разных языках стандарт. Отличие может быть только в деталях, в названиях некоторых ключей.

О том, какие ещё бывают ключи в Ruby можно посмотреть по ссылке.

Добавление данных в файлы

Для того, чтобы записать что-то в файл, нам этот файл нужно сперва открыть, практически точно также, как мы это делали в 13-м уроке.

C той лишь разницей, что мы используем другой ключ: вместо "r:UTF-8" мы напишем "a:UTF-8", потому что файл нам надо открыть для «добавления» (англ. append) строк.

Если такой файл есть, то всё, что мы запишем в файл, будет дописано в конец файла, если же такого файла ещё нет, то будет создан новый файл и всё, что мы запишем в него будет сохранено в этом новом файле.

file = File.new("./file.txt", "a:UTF-8")

Теперь давайте добавим что-нибудь в файл, это делается с помощью метода print у экземпляра класса File:

file.print("Строка для записи в файл\n\r")

Обратите внимание на символы \n\r\ в конце — это символы переноса на следующую строку. Если мы что-то захотим писать в этот файл снова, всё, что мы будем дописывать, начнётся с новой строчки. Так просто красивее и удобнее.

Всегда заканчивайте ваши строки символом переноса строки \n (\r добавляется для пользователей Windows). Ну и как обычно, закроем файл:

file.close

Всё, теперь в новом (если у вас ещё не было файла file.txt) файле записана строка

Строка для записи в файл

Если мы повторно сделаем открытие файла с ключом "a:UTF-8" и проделаем всё заново, но запишем уже другую строку

file = File.new("./file.txt", "a:UTF-8")
file.print("Ещё одна строка\n\r")
file.close

То в файле будет записано уже две строки:

Строка для записи в файл
Ещё одна строка

Итак, когда мы умеем создавать в наших программах новые файлы и дописывать текст в уже существующие, мы можем начать писать нашу программу-дневник.

Пишем программу «Дневник»

Для начала, как обычно, ставим задачу:

Написать программу, которая предлагает пользователю сделать дневниковую запись в консоли, ждёт, пока пользователь напишет текст, а потом сохраняет его, добавив текущее время, в файл с именем в виде текущей даты. Записи в разные дни кладутся в разные файлы, все записи одного и того же дня лежат в одном файле.

Дневник капитана

Задача, как видите, непростая! Но интересная. Приступаем.

Как обычно, создаём отдельную папку для нашей программы: c:\rubytut\lesson16 и в неё создаём файл my_diary.rb (не забудьте сохранить файл в кодировке UTF-8).

Начнём с того, что выведем на экран инструкцию для пользователя с помощью команды puts:

puts "Привет, я твой дневник. Скажи мне что у тебя на уме и в душе?"
puts "Я сохраню всё, что ты напишешь до строчки \"end\" в файл."

current_path = File.dirname(__FILE__)

Обратите внимание — мы снова сохранили путь к программе в переменную current_path (как мы это делали в 13-м уроке).

Теперь давайте спросим у пользователя, что он хочет написать. Как обычно, делаем это с помощью команды STDIN.gets:

line = nil
all_lines = []

while line != "end" do
     line = STDIN.gets.encode("UTF-8").chomp
     all_lines << line
end

all_lines.pop

Мы будем записывать всё, что введёт пользователь в массив all_lines, пока пользователь не введёт end (по-английски маленькими буквами). После выполнения этого блока у нас в массиве all_lines вся нужная нам информация от пользователя (строчка all_lines.pop убирает из массива последний элемент, нам ведь не нужна там строчка с end), осталось только записать её в файл. Новый файл, если это первая запись за сегодня и в уже существующий, если пользователь делает уже не первую запись за день.

Для этого мы заведём переменную time и запишем в неё текущее время

time = Time.now

И с помощью метода strftime в переменную file_name мы запишем строку в формате «2014-11-25» (для удобства сортировки год выводим перед месяцем, а месяц перед днём, соединяем всё дефисами для наглядности):

file_name = time.strftime("%Y-%m-%d")

а в переменную time_string запишем текущее время, как мы это делали в начале нашего урока:

time_string = time.strftime("%H:%M")

Сделаем также строчку с разделителем, которую мы будем писать каждый раз в конце записи, чтобы отделять записи друг от друга внутри одного файла

separator = "------------------------------"

Почти все готово. Осталось только записать в наш файл все строчки этого массива.

Мы будем это делать в цикле for. И на этот раз будем пользоваться не методом print, а методом puts, который также есть у каждого экземпляра класса File. Единственное отличие метода puts от метода print в том, что первый после записи в файл строчки, которую ему передали в параметрах, добавляет ещё перенос строки:

file = File.new("./file.txt", "a:UTF-8")
file.puts("Строка с переносом")
file.close

В файле file.txt будет две строки — первая с текстом «Строка с переносом» и вторая пустая. Итак, пора записать текст дневниковой записи в наш файл:

file = File.new(current_path + "/" + file_name + ".txt", "a:UTF-8")
file.print("\n\r" + time_string + "\n\r")



for item in all_lines do
  file.puts(item)
end

file.puts(separator)
file.close

Обратите внимание, что путь к файлу мы как обычно собрали из нескольких частей:

  • переменной с текущей папкой программы current_path
  • слеша /, чтобы показать, что ищем и создаём файлы в этой папке
  • имени файла, которое храниться в переменной file_name
  • расширения файла .txt

Заканчиваем мы работу программы выводом пользователю сообщения о том, что всё записано.

puts "Ваша запись сохранена в файле #{file_name}.txt"
puts "Запись сделана в #{time_string}"

Пора запускать программу:

cd c:\rubytut\lesson16
ruby my_diary.rb

Чтобы найти ваши записи, вам нужно в проводнике перейти в эту самую папку lesson16.

Как только наиграетесь с программой, можете проверить, что она создаёт файлы для каждого нового дня, делает в них отметку о текущем времени и сохраняет то, что вы написали.