How to create a directory if it does not exist using the File class in Ruby?

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 is if there is no directory named somedir or some_subdir or both in the path, I want it to automatically create it.

How can i do this?

+86
ruby
Sep 27 '12 at 8:30
source share
7 answers

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

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

Edit: here is a solution using only the main libraries (disk overriding, 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 
+102
Sep 27
source share

For those looking for a way to create a directory if it does not exist , here is a simple solution:

 require 'fileutils' FileUtils.mkdir_p 'dir_name' 

Based on Eureka comment .

+52
May 14 '14 at 7:52
source share
 directory_name = "name" Dir.mkdir(directory_name) unless File.exists?(directory_name) 
+14
Mar 03 '15 at 7:36
source share

Based on other answers, nothing happened (failed). There were no errors and no directory was created.

Here is what I need to do:

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

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

+3
Apr 09 '15 at 15:43
source share

Along similar lines (and depending on your structure), so we decided where to store screenshots:

In our program 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

  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? 
+1
Jun 02 '14 at 2:08
source share

The solution "only for the main library" was incomplete. If you want to use only the 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 the FileUtils rmagick file resource prevented my Rails application from deploying to Amazon Web Services, because rmagick depends on the libmagickwand-dev (Ubuntu) / imagemagick (OSX) package working correctly.

0
Dec 04 '16 at 23:12
source share

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) 
0
Oct 13 '17 at 19:10
source share



All Articles