在Ruby中检查目录是否为空

41

如何在Ruby中检查目录是否为空?是否有类似以下的方法:

Dir.exists?("directory")

(我知道那个函数不存在。)


3
我想看到一个名为“Dir.empty?”的方法。 - Ben Flynn
@BenFlynn 五年后,你的愿望已经实现。链接 - Janosch
@Janosch 无论是这个还是引力波存在的证明都是2016年最好的事情。 - Ben Flynn
6个回答

68

现在Ruby有了Dir.empty?,使得这个过程变得非常简单:

Dir.empty?('your_directory') # => (true|false)

在 Ruby 2.4.0 之前,你可以获取一个条目列表并查看其是否为空(考虑“.”和“..”)。请参见文档
(Dir.entries('your_directory') - %w{ . .. }).empty?

# or using glob, which doesn't match hidden files (like . and ..)
Dir['your_directory/*'].empty?

更新:上述第一种方法以前使用正则表达式,但现在已不再使用(显然)。下面的评论大多适用于前者(正则表达式)版本。

第一个给了我错误,但第二个完美地工作了。谢谢! - Mark Szymanski
@Mark Szymanski:啊,是的,我把代码块用括号包起来了。问题已解决。 - coreyward
第一条命令也会忽略隐藏文件,比如.git。 - Pan Thomakos
@Pan Thomakos:不会的。第二个会,但第一个只会拒绝由点组成的文件名。 - coreyward
1
但是 ... 是一个有效的文件名(如 ...., ...),我认为你最好使用显式的 x == '.' || x == '..' 检查,而不是使用正则表达式。确实,... 是一个病态案例,但说出你的意思是一个好主意。 - mu is too short
@mu 我也想过那个,但是觉得这不是很重要,因为它只是一个边缘情况,而第二种方法则完全规避了这个问题。尽管如此,我还是会进行更新以确保它不会在未来给任何人带来麻烦。 - coreyward

11

从 Ruby 2.4.0 开始,有 Dir.empty? 方法。

Dir.empty?('/') # => false

9
您可以使用条目查看目录中的所有文件和文件夹:
Dir.entries('directory')
=> ['.', '..', 'file.rb', '.git']
Dir.entries('directory').size <= 2 # Check if empty with no files or folders.

您也可以使用glob仅搜索文件:

Dir.glob('directory/{*,.*}')
=> ['file.rb', '.git']
Dir.glob('directory/{*,.*}').empty? # Check if empty with no files.

2
但是 Dir.glob('directory/*') 会忽略以 . 开头的文件,例如 .profile.git - mu is too short
@(mu太短了) - 你说得对。我更新了我的正则表达式,包括隐藏文件。 - Pan Thomakos
3
Dir.glob('directory/{,.}') 匹配 "." 和 "..",因此 empty? 函数将始终返回 false。 - Ben Flynn

3

一个空目录应该只有两个链接(.和..)。在OSX上,可以这样处理:

File.stat('directory').nlink == 2

...但在Linux或Cygwin上无法正常工作。(感谢@DamianNowak) 改编Pan的答案:

Dir.entries('directory').size == 2

应该能正常工作。


1
nlink 检查子目录的数量,这是错误的。应该检查 size - Nowaker
@DamianNowak 不是这样的,请尝试使用irb File.stat('。')。nlink http://www.ruby-doc.org/core-1.9.3/File/Stat.html#method-i-nlink - Ben Flynn
必须是特定于操作系统的吗?http://pastie.org/4128791 我正在使用OSX Lion(11.4.0 Darwin) - Ben Flynn
注意到我使用的是Ruby 1.8.7版本。我相信"size"返回的是字节数,因此在OSX上不起作用。如果您能确认您的操作系统和Ruby版本,我建议将其添加到现有的答案中。 - Ben Flynn
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/12880/discussion-between-ben-flynn-and-damian-nowak - Ben Flynn

1
在*nix系统中,虽然不是很直接,但是完美地运作。
Dir.entries(directory_path) == ['.', '..']

0

这是我为此准备的模板。顺便说一下,我正在寻找源代码中特定匹配的文件。

mydir = "/home/to/mydir"

Dir.chdir(mydir)

if Dir.entries(mydir).select(|x| x != '.' && x != '..' && x =~ /\regex.txt\z/).size > 0


       do_something 

elsif Dir.entries(mydir).select(|x| x != '.' && x != '..' && x =~ /\regex.txt\z/).size < 0

      do_something_else 

else 

      puts "some warning message"
end

如果有任何问题,请告诉我 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接