Create Directory if it doesn't exist with Ruby
You are probably trying to create nested directories. Assuming foo
does not exist, you will receive no such file or directory
error for:
Dir.mkdir 'foo/bar'
# => Errno::ENOENT: No such file or directory - 'foo/bar'
To create nested directories at once, FileUtils
is needed:
require 'fileutils'
FileUtils.mkdir_p 'foo/bar'
# => ["foo/bar"]
Edit2: you do not have to use FileUtils
, you may do system call (update from @mu is too short comment):
> system 'mkdir', '-p', 'foo/bar' # worse version: system 'mkdir -p "foo/bar"'
=> true
But that seems (at least to me) as worse approach as you are using external 'tool' which may be unavailable on some systems (although I can hardly imagine system without mkdir
, but who knows).
How do I create directory if none exists using File class in Ruby?
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 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
How do I create a subdirectory if no one exists when writing to a CSV file?
You can do this:
require "fileutils"
csvfile= 'tmp/folder1/folder2/folder3/foo.csv'
FileUtils::mkdir_p File.dirname csvfile
mkdir_p
is line gnu mkdir -p
which creates the directory structure for you, and won't complain if the directory already exists.
dirname
returns the directory name.
If you want specify permissions when creating the directory do this:
FileUtils::mkdir_p( File.dirname(csvfile) , :mode => 0777)
How to create a folder (if not present) with Logger.new?
Try something like this.
dir = File.dirname("#{Rails.root}/log/#{today}/my.log")
FileUtils.mkdir_p(dir) unless File.directory?(dir)
@@my_logger ||= Logger.new("#{Rails.root}/log/#{today}/my.log")
How to create directories recursively in ruby?
Use mkdir_p
:
FileUtils.mkdir_p '/a/b/c'
The _p
is a unix holdover for parent/path you can also use the alias mkpath
if that makes more sense for you.
FileUtils.mkpath '/a/b/c'
In Ruby 1.9 FileUtils was removed from the core, so you'll have to require 'fileutils'
.
Creating directory over SFTP on Ruby fails if directory exists already
In this case, it may be better to simply "ask for forgiveness", then to "ask for permission". It also eliminates a race condition, where you check if the directory exists, discover it doesn't, and then while creating it you error out because it was created by someone else in the meantime.
The following code will work better:
Net::SFTP.start( ip, id, :password => pass, :port=> port ) do |sftp|
begin
sftp.mkdir! remotePath
rescue Net::SFTP::StatusException => e
# verify if this returns 11. Your server may return
# something different like 4.
if e.code == 11
# directory already exists. Carry on..
else
raise
end
end
sftp.upload!(localPath + localfile, remotePath + remotefile)
end
Check if path is a directory path (it might not exist)
TL;DR
If the Pathname isn't on the filesystem already, it's just a name. Its type (e.g. file or directory) isn't fixed until you create a filesystem object with it. So, I recommend either unambiguously constructing each directory Pathname with a trailing separator, or using the Pathname to create the file or directory with the relevant methods for its intended type.
Testing Pathname Objects with Trailing Directory Separator
If you're using the Pathname module, the Pathname doesn't have to exist to be used. In such cases, it's useful to note that the Ruby engine converts forward slashes into backslashes when on Windows, so the following constructed pathnames should work on Windows, Linux, MacOS, and Unix:
Pathname('/some/path/').to_s.end_with? ?/
#=> true
Pathname('C:/some/path/').to_s.end_with? ?/
#=> true
However, if your Pathname is constructed manually or programmatically without being read in from the filesystem or using File#join, you may need to use a character class to check for both *nix and Windows trailing separators. For example:
require 'pathname'
%w[ /some/path/ C:\\some\\path\\ ].map do |path|
Pathname(path).to_s.match? %r![/\\]\z!
end
#=> [true, true]
Using Method to Set Filesystem Object Type
If you construct a path without a trailing directory separator but the directory doesn't actually exist in the filesystem, then you can't determine just from the name whether it's supposed to be a file or directory. A Pathname is really just a special type of String object. The documentation explicitly states (emphasis mine):
Pathname represents the name of a file or directory on the filesystem, but not the file itself.
That being the case, your best bet is to modify your Pathname constructor to ensure that you're building names with trailing separators in the first place. If you can't or won't do that, you will have to leave it up to your filesystem writing code to explicitly call an appropriate method explicitly on the expected filesystem object. For example:
require 'pathname'
require 'fileutils'
path = Pathname '/tmp/foo'
# ensure file or directory doesn't already exist
path.rmtree
# use path as file
FileUtils.touch path
path.file?
#=> true
# remove path before next test
path.unlink
# use path as directory
path.mkpath
path.directory?
#=> true
As you can see, a Pathname without a trailing (back)slash can be used for both files and directories, depending on how you use it.
Ruby unable to create directories
The error is in the line:
line.chomp
It strips the newline from the tail of line
and returns a value that is ignored. It doesn't change the value of line
. It still ends with "\n"
and this is a character that is not allowed in file names on Windows. The code runs fine on Linux and creates directories whose names end in "\n"
.
The solution is also simple. Use #chomp!
instead:
#require 'fileutils'
value=File.open('D:\\exercise\\list.txt').read
value.gsub!(/\r\n?/, "\n")
value.each_line do |line|
line.chomp!
print "FOlder names:#{line}"
Dir.mkdir("D:\\exercise\\#{line}")
end
(It might still produce errors, however, because of empty lines in the input).
FileUtils.mkdir can not create a directory
you need FileUtils.mkdir_p "/tmp/bar/foo"
mkdir_p
behaves exactly as mkdir -p
on UNIXes - if some dir does not exists it will be created.
I bet there are no /tmp/bar
dir and Ruby fails to create a dir into an non-existing folder.
Related Topics
How to Make a Post Request with Open-Uri
Get Sidekiq to Execute a Job Immediately
Do I Have to Manually Uninstall All Dependent Gems
How to Overwrite a Printed Line in the Shell with Ruby
Notices for Sequence After Running Migration in Rails on Postgresql Application
Homebrew Installation on MAC Os X Failed to Connect to Raw.Githubusercontent.Com Port 443
Rails Form Validation Conditional Bypass
How to Express Infinity in Ruby
Differencebetween 'Try' and '&.' (Safe Navigation Operator) in Ruby
Create Custom HTML Helpers in Ruby on Rails
What Does "Shadowing" Mean in Ruby
Inserting an Array Using Sequel Gem in Postgresql
How to Insert Video Youtube API V3 Through Service Account with Ruby
Reflection on Method Parameters in Ruby