Dir.foreach会屈服于什么样的对象?他们正在返回奇怪的尺寸



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

要做到这一点,我说

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

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

问题是,这产生了奇怪的值——总是小于60的整数,当我知道文件夹中有400- 500mb的文件时。所以我读了Ruby文档,它实际上并没有告诉我f在块中变成了什么样的对象。它似乎不是File对象,您可以使用File.open("file.mpg","r")获得的类型,因为如果我使用该方法打开其中一个单独的文件,然后使用.size打印其大小,我就像我所期望的那样以字节为单位返回其文件大小。

那么 f,我如何正确报告文件大小?

问题是您从错误的类开始。假设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返回的值实际上就意味着对象的字节数。

查看文档获取更多信息

Ruby Dir.foreach(...)文档说:

…将每个条目的文件名作为参数传递给块。

文件名是字符串。因此,size返回文件名字符串的长度。

考虑使用File.stat(filename).size,它将返回命名文件的大小(并且您不必像使用普通File那样记住"关闭"它)。

方法如下:

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

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

最新更新