如何在Ruby中递归创建目录?

111

我想把一个文件存储为 /a/b/c/d.txt,但我不知道这些目录是否存在,需要在必要时递归创建它们。 如何在 Ruby 中实现?

6个回答

210

使用 mkdir_p 方法:

FileUtils.mkdir_p '/a/b/c'

_p 是 Unix 遗留下来的表示父级或路径的符号,你也可以使用别名 mkpath,如果更容易理解的话。

FileUtils.mkpath '/a/b/c'

在 Ruby 1.9 版本中, FileUtils 已经不再是核心模块了,因此你需要 require 'fileutils'


9
FileUtilsPathname 可能是 Ruby shell 脚本编程中最重要的工具。 - Jörg W Mittag

23

使用mkdir_p递归创建目录

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

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

6

如果您在运行Unix类机器上,则不要忘记可以通过将其放置在反引号中来在Ruby下运行Shell命令。

`mkdir -p /a/b/c`

保持这么积极真的很难。 - Matthew Schinckel
2
将系统命令弹出到子进程中并不是最好的选择。最好使用Ruby标准库来进行操作,以便进行错误处理、检查结果等。 - noraj

5

Pathname 来拯救!

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

这比被接受的答案更不直观。此外,有关方法forward到FileUtils的文档https://ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/Pathname.html#method-i-mkpath - noraj
1
问题是:“我想将文件存储为 /a/b/c/d.txt,但我不知道这些目录中是否存在任何一个”。我的解决方案允许使用现有的文件路径('/a/b/c/d.txt'),并且无需单独解析即可创建所有文件夹。 - Vadym Tyemirov
你的意思是这个命令可以同时创建目录 /a/b/c 并且创建文件 d.txt 吗? - noraj
1
不需要解析文件名和路径的其余部分,而是允许使用Pathname('/a/b/c/d.txt').dirname.mkpathFile.write('/a/b/c/d.txt', content) - Vadym Tyemirov

3

1
谢谢指点!文档似乎更喜欢使用FileUtils.mkdir_p,所以我采用了它... - Jan
这只是 mkdir_pmkpath 的别名 https://ruby-doc.org/stdlib-2.6.5/libdoc/fileutils/rdoc/FileUtils.html#method-c-mkdir_p - noraj

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/'等。


2
避免重复造轮子。 - noraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接