Errno::ENOENT: No such file or directory ruby

匿名 (未验证) 提交于 2019-12-03 02:48:02

问题:

I am getting the following error:

"Errno::ENOENT: No such file or directory" 

when I try to download a file into a directory that does not exist.

For example:

ftp = Net::FTP.new('example.com') ftp.login files = ftp.chdir('pub/lang/ruby/contrib') files = ftp.list('n*') ftp.getbinaryfile('nif.rb-0.91.gz', 'pub/lang/ruby/contrib/nif.gz', 1024) ftp.close 

However, for many of the files I will be downloading, the full directory path will not exist. For example, until the first file creates pub, it won't exist and this goes for lang/ruby/contrib too.

Is there a method that can check if directories exist and if not create them? I know that there is exist?, but that looks to reference files and it does not create the full path. I figure I need some recursive method to traverse down the folder structure until it hits the filename.

EDIT: mkdir_p seems to be exactly the solution I need.

However, when I use a path of "/a/b/c" I noticed that FileUtils.mkdir_p(File.dirname(localdir)) returns an error: Errno::EACCES: Permission denied - /a

If I remove the "/" in front manually it works. What is causing this? What is the best solution for resolving the error? should I just use the following?

 path="/a/b/c"  if path[0]="/"     path=path[1..-1]  end 

However, I feel like this is just a hack.

回答1:

You can't save to a non-existing path. As the developer you're responsible to make sure your destination paths exist prior to trying to save the file.

Ruby has methods that let you check for the existence a file or directory:

FileUtils.makedirs() is an alias to mkpath, and mkdir_p. I prefer makedirs because it's a mnemonic.

These will also be useful:

Between those two I prefer Dir.chdir, because it takes a block. Any actions that occur inside that block happen in the directory you changed to. At exit, the directory reverts to what it was previously.



回答2:

In the fileutils module you can use mkdir_p which is similar to the mkdir -p command which creates the full path if it doesn't already exist.



回答3:

The analog of *nix mkdir -p, mkdir_p, is what you need, which was provided in the other two answers, but I didn't see anyone address your edit about permissions.

The solution is the user invoking your script requires write permission on the root directory.

The path, "/a/b/c", is addressing the root path ("/"). This is typically only write accessible to the root user or a user that has sudo access.

When you modified the path to remove the leading "/", you told mkdir_p to create the directories "a/b/c" relative to the current working directory instead of relative to the root directory. The reason the modified version works is because the user invoking your ruby script has write permission on the current working directory.

As a personal aside, if consumers of your script are providing the path input, then you probably don't want to remove leading slashes as that can create files/directories in a drastically different place from where the user expects...unless that is the purpose of your program, but make that clear up front.

References:



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!