如果在 Ruby 中没有使用 File 类的目录,那么如何创建目录?

我有这样一个声明:

File.open(some_path, 'w+') { |f| f.write(builder.to_html)  }

在哪里

some_path = "somedir/some_subdir/some-file.html"

我希望发生的是,如果路径中没有名为 somedirsome_subdir的目录,或者两者都没有,我希望它自动创建它。

我该怎么做?

83101 次浏览

您可以使用 FileUtils 递归地创建父目录,如果它们还不存在的话:

require 'fileutils'


dirname = File.dirname(some_path)
unless File.directory?(dirname)
FileUtils.mkdir_p(dirname)
end

编辑: 这里有一个只使用核心库的解决方案(重新实现轮子,不推荐)

dirname = File.dirname(some_path)
tokens = dirname.split(/[\/\\]/) # don't forget the backslash for Windows! And to escape both "\" and "/"


1.upto(tokens.size) do |n|
dir = tokens[0...n]
Dir.mkdir(dir) unless Dir.exist?(dir)
end

对于那些寻找 创建一个不存在的目录之路的人来说,这里有一个简单的解决方案:

require 'fileutils'


FileUtils.mkdir_p 'dir_name'

基于尤里卡的 评论

沿着类似的思路(并且取决于你的结构) ,这是我们如何解决存储截图的地方:

在我们的 env 设置(env.rb)中

screenshotfolder = "./screenshots/#{Time.new.strftime("%Y%m%d%H%M%S")}"
unless File.directory?(screenshotfolder)
FileUtils.mkdir_p(screenshotfolder)
end
Before do
@screenshotfolder = screenshotfolder
...
end

在我们的钩子上

  screenshotName = "#{@screenshotfolder}/failed-#{scenario_object.title.gsub(/\s+/,"_")}-#{Time.new.strftime("%Y%m%d%H%M%S")}_screenshot.png";
@browser.take_screenshot(screenshotName) if scenario.failed?


embed(screenshotName, "image/png", "SCREENSHOT") if scenario.failed?
directory_name = "name"
Dir.mkdir(directory_name) unless File.exists?(directory_name)

根据其他答案,什么都没有发生(不工作)。没有错误,也没有创建目录。

这就是我需要做的:

require 'fileutils'
response = FileUtils.mkdir_p('dir_name')

我需要创建一个变量来捕捉 FileUtils.mkdir_p('dir_name')发送回来的响应... 然后一切都像魔法一样工作!

顶级答案的“核心库”解决方案是不完整的。如果你想只使用核心库,请使用以下方法:

target_dir = ""


Dir.glob("/#{File.join("**", "path/to/parent_of_some_dir")}") do |folder|
target_dir = "#{File.expand_path(folder)}/somedir/some_subdir/"
end


# Splits name into pieces
tokens = target_dir.split(/\//)


# Start at '/'
new_dir = '/'


# Iterate over array of directory names
1.upto(tokens.size - 1) do |n|


# Builds directory path one folder at a time from top to bottom
unless n == (tokens.size - 1)
new_dir << "#{tokens[n].to_s}/" # All folders except innermost folder
else
new_dir << "#{tokens[n].to_s}" # Innermost folder
end


# Creates directory as long as it doesn't already exist
Dir.mkdir(new_dir) unless Dir.exist?(new_dir)
end

我之所以需要这个解决方案,是因为 FileUtils 的依赖 gem rmagick 阻止我的 Rails 应用部署到 Amazon Web Services 上,因为 rmagick 依赖 libmagickwand-dev (Ubuntu)/imagemagick (OSX)包才能正常工作。

使用 Pathname怎么样?

require 'pathname'
some_path = Pathname("somedir/some_subdir/some-file.html")
some_path.dirname.mkdir_p
some_path.write(builder.to_html)