how to get files count in a directory using ruby

2020-05-20 07:14发布

using ruby how to get number of files in a given Directory,the file count should include count from recursive directories.

Eg: folder1(2 files) -----> folder2(4 files) and folder2 is inside folder1. total count for above case should be 6 files.

is there any function in ruby which fetch me this count.

8条回答
我只想做你的唯一
2楼-- · 2020-05-20 07:55

All you need is this, run in the current directory.

Dir["**/*"].length

It counts directories as files.

查看更多
手持菜刀,她持情操
3楼-- · 2020-05-20 07:56

The fastest way should be (not including directories in count):

Dir.glob(File.join(your_directory_as_variable_or_string, '**', '*')).select { |file| File.file?(file) }.count

And shorter:

dir = '~/Documents'
Dir[File.join(dir, '**', '*')].count { |file| File.file?(file) }
查看更多
我只想做你的唯一
4楼-- · 2020-05-20 07:56

How about the following:

find . -typef|wc -l

Also, what are the downsides of using this over Dir.count method?

查看更多
Fickle 薄情
5楼-- · 2020-05-20 08:00

Please try:

//we suppose that the variable folder1 is an absolute path here
pattern = File.join(folder1, "**", "*")
count = Dir.glob(pattern).count
查看更多
女痞
6楼-- · 2020-05-20 08:02

Using ~/Documents as example.

One line code:

Dir['~/Documents'].length

For longer paths one line can be less readable, so:

path = '~/Documents/foo/bar'

Dir[path].length

查看更多
甜甜的少女心
7楼-- · 2020-05-20 08:13

Just now had to find a way to get a list of files from a network share that was taking long with Dir.glob, Filelist from the rake gem seems to be the solution, benchmark follows. Share is on a windows server, script eran on a Windows 10 desktop, Ruby 2.3.0 X64. Netork share had 754 files, frow which 320 CSV's where I was looking for. Some of the files were in subfolders.

require 'rake'
require 'benchmark'

source_path = '//server/share/**/*.csv'
puts FileList.new(source_path).size #320
puts Dir.glob(source_path).length #320
puts Dir[source_path].length #320

Benchmark.bm do |x| 
  x.report("FileList  ") { 1.times { FileList.new(source_path) } }
  x.report("Dir.glob  ") { 1.times { Dir.glob(source_path) } }
  x.report("Dir[]     ") { 1.times { Dir[source_path] } } 
end 

Gives

       user     system      total        real
FileList    0.000000   0.000000   0.000000 (  0.000073)
Dir.glob    0.031000   0.406000   0.437000 ( 11.324227)
Dir[]       0.047000   0.563000   0.610000 ( 11.887771)

Old answer:

Fastest way in windows for very big folders would be to use the command line version of search everything like this, don't know if Linux has something like Search Everything.. If it does, please let us know.

ES = 'C:\Users\...\everything\es\es.exe'

def filelist path
  command = %Q{"#{ES}" "#{path}\\*"}
  list = []
  IO.popen(command+" 2>&1") do |pipe|
    while lijn = pipe.gets
      list << lijn
    end
  end
  list
end

filelist(path).count

see here the results for a relatively small folder (+800 files)

Benchmark.bmbm do |x| 
  x.report("glob      ") { filelist(path).count }
  x.report("everything") { Dir.glob("#{folder}/**/*").count } 
end 

Rehearsal ----------------------------------------------
glob         0.000000   0.032000   0.032000 (  0.106887)
everything   0.000000   0.000000   0.000000 (  0.001979)
------------------------------------- total: 0.032000sec

                 user     system      total        real
glob         0.016000   0.015000   0.031000 (  0.110030)
everything   0.000000   0.016000   0.016000 (  0.001881)
查看更多
登录 后发表回答