如何检测文件是否可以在Ruby中写入?

时间:2016-03-18 20:45:17

标签: ruby macos file-io

如果其中任何一个为真,则该函数应返回false:

  1. 完整路径是现有目录。
  2. 路径不是合法的文件名(无效字符,太长等)
  3. 路径指的是当前用户无法写入的现有文件。
  4. 路径包括尚不存在的任何目录段。
  5. 如果所有这些都为真,则该函数应返回true:

    1. 除文件名以外的所有路径段都已存在。
    2. 该文件不存在或存在且可由当前用户写入。
    3. 当前用户可以写入保存文件的目录。
    4. 路径段和文件名不会太长,只能由文件名的有效字符组成。
    5. 指定了相对或绝对路径。
    6. 该功能必须使用Ruby 1.9.3在MAC OSX上运行。

      当文件不存在且应该是可写的时,以下方法返回false,即使我从我自己的用户目录的子目录运行它:

      File.writable?('./my-file-name')
      

      我会接受一个解决方案,包括调用文件打开并在写入失败时捕获异常,但我更喜欢不依赖异常。

      这是我到目前为止所做的,但它没有处理一些边缘情况:

        def file_writable?(filename)
          return false if (filename || '').size == 0
          return false if File.directory?(filename)
          return false if File.exists?(filename) && !File.writable(filename)
          return true;
        end
      

      我仍然不知道如何方便地测试是否缺少任何目录段,或者名称中是否有奇怪的字符以及其他一些情况。

1 个答案:

答案 0 :(得分:2)

Ruby在其std-lib中包含Pathname,它是几个其他面向文件的类的包装器:

  

包括File,FileTest以及Dir和FileUtils中的一些功能,这是一种不足为奇的方式。它本质上是所有这些的外观,甚至更多。

A"路径名"可以是目录或文件。

路径名并不能完成您需要的所有事情,但它可以作为一个非常方便的起点。您可以轻松添加所需的其他功能,因为它是一个包装器,比您尝试使用各个类实现解决方案要容易得多。

当我不得不进行大量的目录/文件处理时,这是我的课程。

require 'pathname'  # => true

foo = Pathname.new('/usr/bin/ruby')  # => #<Pathname:/usr/bin/ruby>
foo.writable?                        # => false
foo.directory?                       # => false
foo.exist?                           # => true

tmp = Pathname.new('/tmp/foo')  # => #<Pathname:/tmp/foo>
tmp.write('bar')                # => 3
tmp.writable?                   # => true
tmp.directory?                  # => false
tmp.exist?                      # => true

bin = Pathname.new('/usr/bin')  # => #<Pathname:/usr/bin>
bin.writable?                   # => false
bin.directory?                  # => true
bin.exist?                      # => true

fake = Pathname.new('/foo/bar')  # => #<Pathname:/foo/bar>
fake.exist?                      # => false

您无法分辨目录中缺少哪些组件,但通常我们会尝试创建它并在发生异常时解救该异常,从而处理权限错误。编写代码以查找完整的目录路径并不困难,然后如果全路径不存在则遍历目录链,将每个路径作为前一个路径的子路径查找。 <{3}} findfind_all会很有用。