【问题标题】:Create Directory if it doesn't exist with Ruby如果 Ruby 不存在目录,则创建目录
【发布时间】:2013-10-09 18:57:15
【问题描述】:

我正在尝试使用以下代码创建目录:

Dir.mkdir("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")
    unless File.exists?("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")  

但是,我收到了这个错误:

没有这样的文件或目录 - /Users/Luigi/Desktop/Survey_Final/Archived/Survey/test (Errno::ENOENT)

为什么上面的Dir.mkdir 语句没有创建这个目录?

【问题讨论】:

  • File.exists?() 适用于文件和文件夹。它不知道有什么区别。

标签: ruby


【解决方案1】:

您可能正在尝试创建嵌套目录。假设foo 不存在,您将收到no such file or directory 错误:

Dir.mkdir 'foo/bar'
# => Errno::ENOENT: No such file or directory - 'foo/bar'

要一次创建嵌套目录,需要FileUtils

require 'fileutils'
FileUtils.mkdir_p 'foo/bar'
# => ["foo/bar"]

Edit2:你不必使用FileUtils,你可以做系统调用(@mu 更新太短的评论):

> system 'mkdir', '-p', 'foo/bar' # worse version: system 'mkdir -p "foo/bar"'
=> true

但这似乎(至少在我看来)比您使用外部“工具”更糟糕的方法,这在某些系统上可能不可用(虽然我很难想象没有mkdir 的系统,但谁知道)。

【讨论】:

  • system 'mkdir', '-p', 'foo/bar' 将是 system 调用的更好版本。不需要额外的 shell 进程或 system 的单参数版本附带的通常的引用/转义/注入废话。
  • system 将启动/bin/sh 以解析mkdir -p "foo/bar" 字符串,然后shell 将运行/bin/mkdir。因此,您正在做额外的工作(创建命令字符串,启动 /bin/sh 以再次将其拆开)并且其中一些额外的工作使您容易受到 shell 注入攻击(花一些时间在 Ruby 的 CERT 公告中,您将看看这个问题有多普遍)。
  • @muistooshort @zrl3dx system 呼叫又如何比 fileutils 更好?我在 Windows 上,mkdir_p 工作得很好,无需生成子 shell 来解析 mkdir -p 无论如何都会失败。很高兴fileutils 是答案中的第一个选择。
  • @TWiStErRob:再看我的cmets,我没说fileutilsmkdir_p,我只是说system command, arg1, arg2, ...system command_with_arguments好。
  • @muistooshort 啊,对不起,所以你只是说有更好的方法来做坏的选择:)
【解决方案2】:

简单的方法:

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

【讨论】:

  • 应该使用 File.directory 吗?而不是 File.exists?
  • 假设有一个同名的普通文件。在这种情况下,您无法创建目录。
  • 它还创建了一个竞争条件。该文件可以在检查之后创建之前创建。
  • @DonReba 怎么样?方法 File.exists 吗?和 Dir.mkdir 异步?
  • @Licysca 请考虑更新您的答案。这不是一个干净的答案,而且得到了不合理的支持。
【解决方案3】:

另一种简单的方法:

Dir.mkdir('tmp/excel') unless Dir.exist?('tmp/excel')

【讨论】:

  • 如果你想创建嵌套目录,那么这不起作用。例如,我想创建以下目录/home/jignesh/reports/test,但使用此解决方案引发了RUBY (Errno::ENOENT), no such file or directory @ dir_s_mkdir。所以可靠的解决方案是使用FileUtils.mkdir_p
【解决方案4】:

Dir.mkdir('dir') rescue nil 怎么样?

【讨论】:

  • 避免在其修饰符形式中使用rescue
  • 想解释一下为什么我应该写 5 行代码而不是 1 行代码?我想看看你试试看。
  • 我已经做过了,我完全不同意,我认为这很愚蠢,所以也许你能启发我?
  • 这将捕获 any 异常,这不是您想要做的,并且在现实世界的应用程序中会隐藏使维护更加困难的问题。此外,将异常用作条件不是一个好主意,从硬件角度来看,它们的运行速度要慢得多(在现代语言中可能不是真正的问题,但仍然会让你看起来缺乏编码经验)。
猜你喜欢
  • 2018-08-01
  • 2017-01-01
  • 1970-01-01
  • 2014-05-19
  • 2016-02-02
  • 1970-01-01
  • 2015-05-10
相关资源
最近更新 更多