How can I detect whether a file is writeable in Ruby?

The function should return false if any of these are true:

  • The complete path is an existing directory.
  • The path is not a legal file name (invalid characters, too long, etc.)
  • The path refers to an existing file that is not writeable by current user.
  • The path includes any directory segments that do not already exist.
  • The function should return true if all of these are true:

  • All path segments except the file name are already existing directories.
  • The file either does not already exist or exists and is writable by the current user.
  • The directory that will hold the file is writable by the current user.
  • The path segments and filename are not too long and are composed only of valid characters for filenames.
  • A relative or absolute path is specified.
  • The function must work on MAC OSX using Ruby 1.9.3.

    The following method returns false when the file does not already exist and should be writable, even though I am running it from a subdirectory of my own user directory:

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

    I will accept a solution involving calling file open and catching the exception if a write fails, though I prefer to not rely on exceptions.

    Here is what I have so far, but it does not handle some edge cases:

      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
    

    I still do not know how to conveniently test if any directory segments are missing, or if weird characters are in the name, and some other cases.


    Ruby includes Pathname in its std-lib, which is a wrapper around several other file-oriented classes:

    All functionality from File, FileTest, and some from Dir and FileUtils is included, in an unsurprising way. It is essentially a facade for all of these, and more.

    A "pathname" can be a directory or a file.

    Pathname doesn't do all the things you require, however it acts as a very convenient starting point. You can easily add the additional functionality you need since it is a wrapper, much easier than if you tried to implement a solution using the individual classes.

    It's my go-to class when I have to do a lot of directory/file processing.

    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
    

    You can't tell what components are missing from a directory, but normally we'd try to create it and rescue the exception if it occurs, dealing with permission errors. It wouldn't be hard to write code to look for a full directory path, then iterate though the chain of directories if the full-path doesn't exist, looking for each as a child of the previous one. Enumerable's find and find_all would be useful.

    链接地址: http://www.djcxy.com/p/60406.html

    上一篇: 编写我自己的3D游戏引擎

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