根据大小排序

目前,该程序按字母顺序打印文件和目录名称及其大小。但我对它们的相对大小更感兴趣。因此,如果文件按大小而不是按名称排序,则会更有用。

为了能够对文件进行排序,我们需要一些方法来存储所有文件大小的完整列表。一种显而易见的方法是将文件大小添加到数组中。在 file_info2.rb 中,我创建了一个空数组 $files,并且每次处理文件时,我都会将其大小附加到数组中:

file_info2.rb
  1. $files << fsize

然后,我可以对文件大小进行排序,以显示从低到高的值或(通过排序然后反转数组),从高到低的值:

  1. $files.sort # sort low to high
  2. $files.sort.reverse # sort high to low

唯一的问题是我现在最终得到一个没有相关文件名的文件大小数组。更好的解决方案是使用 Hash 而不是 Array。我在 file_info3.rb 中完成了这个。首先,我创建两个空 Hash:

file_info3.rb
  1. $dirs = {}
  2. $files = {}

现在,当 processfiles 方法遇到目录时,它会向 $dirs 哈希添加一个新元素,使用完整目录路径 mypath 作为键,目录大小 dsize 作为值:

  1. $dirs[mypath] = dsize

同样的将键值对添加到 $files 哈希中。当通过递归调用 processfiles 方法处理子目录和文件的整个结构时,$dirs 哈希变量将包含目录名和大小的键值对,$files 哈希将包含文件名的键值对和大小。

现在剩下的就是对这些哈希进行排序和显示。Hash 的标准排序方法是对键进行排序,而不是值。 我想根据值(大小)排序,而不是根据键(名称)。为了做到这一点,我已经定义了这个自定义排序方法:

  1. $files.sort{|a,b| a[1]<=>b[1]

这里 sort 遍历将(directory-walking) $files 哈希转换为 [key,value] 对的嵌套数组,并将其中的两个作为 ab 传递到花括号之间的块中。每个 [key,value] 对的第二项(在索引 [1] 处)提供值。使用 Ruby 的 <=> 比较方法对值进行排序。最终结果是,该程序现在首先按升序(按大小)显示文件列表,然后类似的显示排序的目录列表。