如果Ruby中的File类不存在,如何创建目录?

时间:2021-03-04 07:11:43

I have this statement:

我有这种说法:

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

Where

在哪里

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

What I want to happen is, if there is no directory called somedir or some_subdir or both in the path, I want it to automagically create it.

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

How can I do that?

我怎么做呢?

7 个解决方案

#1


114  

You can use FileUtils to recursively create parent directories, if they are not already present:

如果尚未存在,可以使用FileUtils递归创建父目录:

require 'fileutils'

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

Edit: Here is a solution using the core libraries only (reimplementing the wheel, not recommended)

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

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

#2


58  

For those looking for a way to create a directory if it doesn't exist, here's the simple solution:

对于那些想要创建一个不存在的目录的人,这里有一个简单的解决方案:

require 'fileutils'

FileUtils.mkdir_p 'dir_name'

Based on Eureka's comment.

基于尤里卡的评论。

#3


16  

directory_name = "name"
Dir.mkdir(directory_name) unless File.exists?(directory_name)

#4


4  

Based on others answers, nothing happened (didn't work). There was no error, and no directory created.

根据别人的回答,什么也没有发生(不管用)。没有错误,也没有创建目录。

Here's what I needed to do:

以下是我需要做的:

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

I needed to create a variable to catch the response that FileUtils.mkdir_p('dir_name') sends back... then everything worked like a charm!

我需要创建一个变量来捕获FileUtils.mkdir_p('dir_name')返回的响应……然后一切都像魔法一样奏效了!

#5


1  

Along similar lines (and depending on your structure), this is how we solved where to store screenshots:

按照类似的思路(取决于您的结构),这就是我们解决在哪里存储屏幕截图的方法:

In our env setup (env.rb)

在我们的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

And in our hooks.rb

在我们hooks.rb

  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?

#6


1  

The top answer's "core library" only solution was incomplete. If you want to only use core libraries, use the following:

上面的答案是“核心库”,唯一的解决方案是不完整的。如果您只想使用核心库,请使用以下内容:

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

I needed this solution because FileUtils' dependency gem rmagick prevented my Rails app from deploying on Amazon Web Services since rmagick depends on the package libmagickwand-dev (Ubuntu) / imagemagick (OSX) to work properly.

我需要这个解决方案,因为FileUtils的依赖gem rmagick阻止了我的Rails应用程序在Amazon Web服务上部署,因为rmagick依赖于软件包libmagickwanddev (Ubuntu) / imagemagick (OSX)来正常工作。

#7


0  

How about using Pathname?

使用路径名怎么样?

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

#1


114  

You can use FileUtils to recursively create parent directories, if they are not already present:

如果尚未存在,可以使用FileUtils递归创建父目录:

require 'fileutils'

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

Edit: Here is a solution using the core libraries only (reimplementing the wheel, not recommended)

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

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

#2


58  

For those looking for a way to create a directory if it doesn't exist, here's the simple solution:

对于那些想要创建一个不存在的目录的人,这里有一个简单的解决方案:

require 'fileutils'

FileUtils.mkdir_p 'dir_name'

Based on Eureka's comment.

基于尤里卡的评论。

#3


16  

directory_name = "name"
Dir.mkdir(directory_name) unless File.exists?(directory_name)

#4


4  

Based on others answers, nothing happened (didn't work). There was no error, and no directory created.

根据别人的回答,什么也没有发生(不管用)。没有错误,也没有创建目录。

Here's what I needed to do:

以下是我需要做的:

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

I needed to create a variable to catch the response that FileUtils.mkdir_p('dir_name') sends back... then everything worked like a charm!

我需要创建一个变量来捕获FileUtils.mkdir_p('dir_name')返回的响应……然后一切都像魔法一样奏效了!

#5


1  

Along similar lines (and depending on your structure), this is how we solved where to store screenshots:

按照类似的思路(取决于您的结构),这就是我们解决在哪里存储屏幕截图的方法:

In our env setup (env.rb)

在我们的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

And in our hooks.rb

在我们hooks.rb

  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?

#6


1  

The top answer's "core library" only solution was incomplete. If you want to only use core libraries, use the following:

上面的答案是“核心库”,唯一的解决方案是不完整的。如果您只想使用核心库,请使用以下内容:

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

I needed this solution because FileUtils' dependency gem rmagick prevented my Rails app from deploying on Amazon Web Services since rmagick depends on the package libmagickwand-dev (Ubuntu) / imagemagick (OSX) to work properly.

我需要这个解决方案,因为FileUtils的依赖gem rmagick阻止了我的Rails应用程序在Amazon Web服务上部署,因为rmagick依赖于软件包libmagickwanddev (Ubuntu) / imagemagick (OSX)来正常工作。

#7


0  

How about using Pathname?

使用路径名怎么样?

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