我是Ruby的新手(作为Java开发人员)并尝试实现一种方法(哦,抱歉,一个函数),它将以递归方式检索和生成子目录中的所有文件。
我已将其实施为:
def file_list_recurse(dir)
Dir.foreach(dir) do |f|
next if f == '.' or f == '..'
f = dir + '/' + f
if File.directory? f
file_list_recurse(File.absolute_path f) { |x| yield x }
else
file = File.new(f)
yield file
end
end
end
我的问题是:
由于
PS: 我的方法的示例用法是这样的:
curr_file = nil
file_list_recurse('.') do |file|
curr_file = file if curr_file == nil or curr_file.ctime > file.ctime
end
puts curr_file.to_path + ' ' + curr_file.ctime.to_s
(这将从树中获取最旧的文件)
==========
所以,感谢@buruzaemon我找到了很棒的Dir.glob函数,它为我节省了几行代码。 另外,感谢@Casper,我发现了File.stat方法,它使我的函数运行速度比File.new快两倍
最后,我的代码看起来像这样:
i=0
curr_file = nil
Dir.glob('**/*', File::FNM_DOTMATCH) do |f|
file = File.stat(f)
next unless file.file?
i += 1
curr_file = [f, file] if curr_file == nil or curr_file[1].ctime > file.ctime
end
puts curr_file[0] + ' ' + curr_file[1].ctime.to_s
puts "total files #{i}"
=====
默认情况下,Dir.glob会忽略以点开头的文件名(在* nix中被视为'隐藏'),因此添加第二个参数File :: FNM_DOTMATCH
非常重要答案 0 :(得分:11)
这个怎么样?
puts Dir['**/*.*']
答案 1 :(得分:5)
根据文档File.new
确实打开了文件。您可能希望使用File.stat
,它将与文件相关的统计信息收集到可查询对象中。但请注意,统计数据是在创建时收集的。不是在调用ctime
等查询方法时。
示例:
Dir['**/*'].select { |f| File.file?(f) }.map { |f| File.stat(f) }
答案 2 :(得分:5)
这件事告诉我要考虑接受答案,我希望我不介意自己回答:
i=0
curr_file = nil
Dir.glob('**/*', File::FNM_DOTMATCH) do |f|
file = File.stat(f)
next unless file.file?
i += 1
curr_file = [f, file] if curr_file == nil or curr_file[1].ctime > file.ctime
end
puts curr_file[0] + ' ' + curr_file[1].ctime.to_s
puts "total files #{i}"
答案 3 :(得分:2)
答案 4 :(得分:1)
如果您在Windows上,请在此处查看我的答案,比标准Ruby Dir更快(~26次)。如果你使用mtime,它仍然可以更快地使用。
如果您使用其他操作系统,您可以使用相同的技术,我很好奇,如果收益会那么大,但我几乎可以肯定。
How to find the file path of file that is not the current file in ruby