检查文件/文件夹是否在Ruby的子目录中

时间:2016-09-19 20:44:31

标签: ruby file

检查给定文件/目录是否在某个其他目录(或其子目录之一)中最好的方法是什么?平台独立性和绝对/相对路径处理会很好。

一种简单的方法就是搜索文件并每次检查,但也许有更好的文件。

e.g。给定目录AA位于以B为根的目录子树中的任何位置,即is_underneath?(A,B)或其他内容。

2 个答案:

答案 0 :(得分:4)

一个好的,快速的方法是在Ruby stdlib中使用Dir类提供的glob方法。

glob( pattern, [flags] ) # => matches
  

扩展模式,它是一个模式数组或模式字符串,并将结果作为匹配或作为赋予块的参数返回。

适用于文件和目录,并允许您递归搜索。 它返回一个数组,其中的文件/目录与模式匹配,如果没有人匹配,它将为空。

root = '/my_root'
value = 'et_voila.txt'

Dir.glob("#{root}/**/#{value}")

# ** Matches directories recursively.

# or you can pass also the relative path
Dir.glob("./foo/**/#{value}")

答案 1 :(得分:2)

我希望我理解你的问题是正确的。

一个例子:

require 'pathname'

A = '/usr/xxx/a/b/c.txt'
path = Pathname.new(A)

[
  '/usr/xxx/a/b',
  '/usr/yyy/a/b',
].each{|b|

  if path.fnmatch?(File.join(b,'**')) 
    puts "%s is in %s" % [A,b]
  else
    puts "%s is not in %s" % [A,b]
  end
}

结果:

/usr/xxx/a/b/c.txt is in /usr/xxx/a/b
/usr/xxx/a/b/c.txt is not in /usr/yyy/a/b

解决方案使用class Pathname。它的一个优点:Pathname表示文件系统上的文件或目录的名称,但不代表文件本身。因此,您可以在没有文件读取权限的情况下进行测试。

测试本身使用Pathname#fnmatch?和glob-pattern File.join(path,'**')**表示所有子目录)。

如果您经常需要,可以延长Pathname

require 'pathname'
class Pathname
  def is_underneath?(path)
    return self.fnmatch?(File.join(path,'**'))
  end
end

A = '/usr/xxx/a/b/c.txt'
path = Pathname.new(A)

[
  '/usr/xxx/a/b',
  '/usr/yyy/a/b',
].each{|b|
  if path.is_underneath?(b)
    puts "%s is in %s" % [A,b]
  else
    puts "%s is not in %s" % [A,b]
  end
}

要处理绝对/相对路径,可能有助于扩展这些路径(抱歉,这是未经测试的)。

class Pathname
  def is_underneath?(path)
    return self.expand_path.fnmatch?(File.expand_path(File.join(path,'**')))
  end
end