Как рекурсивно создавать каталоги в Ruby?


102

Я хочу сохранить файл как /a/b/c/d.txt, но я не знаю, существует ли какой-либо из этих каталогов, и мне нужно рекурсивно создавать их при необходимости. Как это сделать в рубине?

Ответы:


198

Использование mkdir_p:

FileUtils.mkdir_p '/a/b/c'

Это _pудержание unix для parent / path, вы также можете использовать псевдоним, mkpathесли это имеет для вас больше смысла.

FileUtils.mkpath '/a/b/c'

В Ruby 1.9 FileUtils был удален из ядра, поэтому вам придется require 'fileutils'.


9
+1. FileUtilsи Pathname, вероятно, являются наиболее важными инструментами для написания сценариев оболочки Ruby.
Jörg W Mittag

21

Используйте mkdir_p для рекурсивного создания каталога

path = "/tmp/a/b/c"

FileUtils.mkdir_p(path) unless File.exists?(path)

6

Если вы работаете на unixy-машинах, не забывайте, что вы всегда можете запустить команду оболочки под ruby, поместив ее в обратные кавычки.

`mkdir -p /a/b/c`

Хотя быть таким позитивным - это хорошо.
Мэтью Шинкель

1
Вставлять системную команду в подпроцесс - не лучшая идея. Лучше сделать это со стандартной библиотекой Ruby, чтобы получить обработку ошибок, проверить результат и т. Д.
noraj


2

Путь на помощь!

Pathname('/a/b/c/d.txt').dirname.mkpath

Это менее интуитивно понятно, чем принятый ответ. Также документ для метода пересылается в FileUtils ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/…
noraj 07

Возникает вопрос: «Я хочу сохранить файл как /a/b/c/d.txt, но не знаю, существует ли какой-либо из этих каталогов». Мое решение позволяет использовать существующий путь к файлу ('/a/b/c/d.txt') и без отдельного анализа создавать все папки.
Вадим Темиров

Вы имеете в виду, что это позволяет делать FileUtils.mkdir_p '/a/b/c'+ создавать d.txtодновременно?
noraj

Неа, вместо этого разрешает Pathname('/a/b/c/d.txt').dirname.mkpathи File.write('/a/b/c/d.txt', content)без filename = '/a/b/c/d.txt'.rpartition('/').lastи остальной парсинг,
Вадим Тёмиров

0

Вы также можете использовать свою собственную логику

def self.create_dir_if_not_exists(path)
  recursive = path.split('/')
  directory = ''
  recursive.each do |sub_directory|
    directory += sub_directory + '/'
    Dir.mkdir(directory) unless (File.directory? directory)
  end
end

Итак, если путь равен 'tmp / a / b / c', если 'tmp' не существует, создается 'tmp', затем 'tmp / a /' и так далее, и так далее.


Можно было бы не изобретать велосипед.
noraj
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.