Найти тему
Ruby-разработчик

Как создавать временные файлы на Руби

Оглавление

Это перевод оригинальной статьи от Jesus Castello.

Создавая временный файл, вы получите пустой файл со случайным именем внутри каталога с временными файлами вашей ОС (Операционной Системы).

Этот файл будет удалён автоматически.

Как это сделать на Ruby?

Как-то так:

Где f — это ваш файл, а << пишет в него.

Это встроено в Ruby, поэтому не нужно устанавливать какие-либо гемы.

Ну, отлично.

Это достаточно просто, но вы, возможно, всё ещё имеете ряд вопросов.

Таких, как:

  • Когда именно файл удаляется?
  • Почему я ничего не могу считать с моего временного файла?
  • Если ли гарантии, что временные файлы будут уникальными?

Я собираюсь ответить не только на эти вопросы, так что у вас будет гораздо более глубокое понимание!

В чем разница между new и create?

Вы могли заметить, что класс Tempfile имеет два метода для создания файлов.

Один из них — new, другой это create.

В чём разница?

Согласно документации, метод new создаёт объект класса Tempfile (как и следовало ожидать), а create даёт вам объект File.

Я не думаю, что это реально имеет значение, потому что Tempfile и так делегирует File.

По-настоящему, разница в том, что create принимает блок, а new — нет.

Попробуйте сами:

Вы получите вот это полезное предупреждение:

# warning: Tempfile.new doesn't call the given block.

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

Отсюда следующий вопрос…

Всё-таки, когда временный файл будет удалён?

Вы можете непосредственно управлять удалением как временного, так и обычного файла используя метод delete или create с блоком.

Автоматическое удаление работает, когда:

  • Ваша программа заканчивает выполнение
  • Ваши файлы попадаются «сборщику мусора», другими словами, файлы удаляются с диска, благодаря алгоритму освобождения места

Последнее может произойти только если ваша программа уже никогда не ссылается на файл.

Похоже на переменные.

Вот, что я имел в виду:

Временный файл может быть удалён, когда t выходит за пределы области видимости.

Если вы используете Linux, то вам доступен очень интересный инструмент для наблюдения за создаваемыми и удаляемыми файлами — inotify-tools.

Попробуйте эту команду:

Затем, запустите код на Ruby, который создаёт файлы.

Например, такой:

Вы увидите что-то вроде этого:

Результат работы inotifywait
Результат работы inotifywait

Почему недоступно чтение из вашего временного файла?

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

Пример:

Пример чтения данных из временного файла
Пример чтения данных из временного файла

Почему так?

Оказывается, что файлы — это объекты ввода-вывода.

У объектов ввода-вывода есть указатель позиции, и когда вы записываете в файл, эта позиция сдвигается вперёд.

Поэтому, если вы хотите считать данные из файла, вы должны установить этот указатель в начало.

Вот так:

Пример правильного чтения из временного файла
Пример правильного чтения из временного файла

Вы можете, также, обнулить содержимое файла.

Пример:

Сброс содержимого временного файла
Сброс содержимого временного файла

Временные файлы действительно уникальны?

Tempfile создаёт уникальное имя и устанавливает права доступа на 600 — это означает, что только пользователь создавший файл, сможет прочитать его.

Но может ли так случиться, что появится дубликат этого имени?

Вот что говорит документация:

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

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

И было бы неплохо отметить, что вы можете установить префикс для ваших фалов.

Как здесь:

Создание временного файла с префиксом
Создание временного файла с префиксом

Это уменьшает вероятность появления коллизий.

Открытие временного файла в бинарном режиме

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

Бинарный режим предотвратит конвертирование символа конца строки из одного вида в другой (прим.пер. — уже почти не актуально).

В результате данные не будут при считывании и записи интерпретироваться как текст.

Бинарный режим не включен по умолчанию:

Проверка на бинарный режим
Проверка на бинарный режим

Вы должны включить его, как показано здесь:

Включение бинарного режима
Включение бинарного режима

Это работает и с методом create:

Создание бинарного файла в методе create
Создание бинарного файла в методе create

Заключение

Вы узнали как работать с временными файлами в Ruby, используя класс Tempfile!

И сейчас самое время для практики.

Спасибо за то, что прочитали до конца!

Источник.