Dir.foreach会产生什么样的物体?他们正在回归奇怪的尺寸

时间:2014-05-16 16:48:03

标签: ruby

我正在尝试遍历目录中的每个文件,并输出其文件名和文件大小。

为此,我说

Dir.foreach(files) do |f|
    puts f.size
end

对于'files'目录中的每个文件,将其filesize打印到屏幕上。

问题是,当我知道文件夹中有400-500 MB文件时,这会产生奇怪的值 - 总是低于60的整数。所以我阅读了Ruby文档,它实际上并没有告诉我块内有什么类型的对象f。它似乎不是File对象,是File.open("file.mpg","r")所带来的类型,因为如果我使用该方法打开其中一个单独的文件,然后使用{{打印它的大小1}},就像我说的那样,我以字节为单位取回它的文件大小。

那么 .size,我该如何正确报告文件大小?

3 个答案:

答案 0 :(得分:1)

这是一种方式:

Dir.foreach(files) do |f|
    puts File.size(f) if File.file?(f)
end

f是文件名,但它是字符串。查看此File::size以获取文件 size

答案 1 :(得分:1)

Ruby Dir.foreach(...) docs说:

  

...将每个条目的 filename 作为参数传递给块。

文件名是字符串。因此,size会返回length of the filename string

考虑使用File.stat(filename).size,它将返回指定文件的大小(并且您不必像平原File那样记得“关闭”它。

答案 2 :(得分:1)

问题是你是从错误的班级开始的。你假设Dir会返回一些派生类的对象。相反,使用Ruby的Pathname类:

require 'pathname'

Pathname.new(ENV['HOME']).children.each do |pname|
  puts pname.to_s
  puts pname.size
end
# >> /home/tinman/applications
# >> 102
# >> /home/tinman/bin
# >> 1020
# >> /home/tinman/development
# >> 1054
# >> /home/tinman/documents
# >> 884
# >> /home/tinman/downloads
# >> 612
# >> /home/tinman/src
# >> 136
# >> /home/tinman/tmp
# >> 102
# >> /home/tinman/vim
# >> 612

块中pname的值是Pathname对象:

Pathname.new(ENV['HOME']).children.first.class # => Pathname

上面的“大小”实际上不是字节,它们是目录分配的大小,因为它们实际上是列出的目录。

如果我查看包含文件的目录,我可以看到文件的大小,以字节为单位:

require 'pathname'

Pathname.new(ENV['HOME']).join('tmp').children.each do |pname|
  puts pname.to_s
  puts pname.size
end

# >> /home/tinman/tmp/binary_search_file~
# >> 1812

换句话说,你必须知道你在看什么;仅仅因为它在磁盘上并不意味着值size返回实际上意味着对象中的字节数。

有关详细信息,请参阅the documentation