【问题标题】:Getting accurate file size in megabytes?以兆字节为单位获取准确的文件大小?
【发布时间】:2011-06-02 14:27:47
【问题描述】:

如何获得以 MB 为单位的准确文件大小?我试过这个:

compressed_file_size = File.size("Compressed/#{project}.tar.bz2") / 1024000

puts "file size is #{compressed_file_size} MB"

但它削减了 0.9 并显示 2 MB 而不是 2.9 MB

【问题讨论】:

  • 与浮点数与整数问题分开 - 1024000 真的是您想要的常数吗?通常MB是2^20,也就是1048576。
  • 感谢您的来信。我在我的代码中修复了这个问题。
  • 根据您想要的功能齐全程度,Rails 的ActionView::Helpers::NumberHelper#number_to_human_size 的源代码是一个很好的参考实现。 apidock.com/rails/ActionView/Helpers/NumberHelper/…
  • 知道这是旧的,但正在发生的事情是你除以一个整数,它返回整数,又名。砍数字。如果您在末尾添加.0,它将使用浮点数进行计算。所以:compressed_file_size = ... .... / 1024000.0 应该给你浮点数。您可能需要在File.size(...) 上添加.to_f

标签: ruby


【解决方案1】:

试试:

compressed_file_size = File.size("Compressed/#{project}.tar.bz2").to_f / 2**20
formatted_file_size = '%.2f' % compressed_file_size

单线:

compressed_file_size = '%.2f' % (File.size("Compressed/#{project}.tar.bz2").to_f / 2**20)

或:

compressed_file_size = (File.size("Compressed/#{project}.tar.bz2").to_f / 2**20).round(2)

关于%-String 运算符的更多信息: http://ruby-doc.org/core-1.9/classes/String.html#M000207


顺便说一句:如果我使用 base2 计算,我更喜欢“MiB”而不是“MB”(请参阅​​:http://en.wikipedia.org/wiki/Mebibyte

【讨论】:

    【解决方案2】:

    您正在执行整数除法(这会删除小数部分)。尝试除以 1024000.0 以便 ruby​​ 知道您想要进行浮点数学运算。

    【讨论】:

    • 我什至不使用 Ruby,而这正是我要建议的。
    • 这个也是。它给了我 2.8679921875 MB 我只想要 2.86 MB
    【解决方案3】:

    试试:

    compressed_file_size = File.size("Compressed/#{project}.tar.bz2").to_f / 1024000
    

    【讨论】:

    • 这给了我 2.8679921875 MB 我只想要 2.86 MB
    • 你可以使用compressed_file_size.round(2) 或'.2f' %compressed_file_size 输出
    • 我没有得到 '.2f' %compressed_file_size 输出。请澄清。
    • puts "文件大小为 #{'.2f' %compressed_file_size} MB"
    • 尝试:formatted_file_size = '%.2f' % compressed_file_size -- 格式字符串中缺少“%”。有关%-String 运算符的更多信息:(ruby-doc.org/core-1.9/classes/String.html#M000207)
    【解决方案4】:

    您可能会发现格式化函数很有用 (pretty print file size),这是我的示例,

    def format_mb(size)
      conv = [ 'b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb' ];
      scale = 1024;
    
      ndx=1
      if( size < 2*(scale**ndx)  ) then
        return "#{(size)} #{conv[ndx-1]}"
      end
      size=size.to_f
      [2,3,4,5,6,7].each do |ndx|
        if( size < 2*(scale**ndx)  ) then
          return "#{'%.3f' % (size/(scale**(ndx-1)))} #{conv[ndx-1]}"
        end
      end
      ndx=7
      return "#{'%.3f' % (size/(scale**(ndx-1)))} #{conv[ndx-1]}"
    end
    

    测试一下,

    tries = [ 1,2,3,500,1000,1024,3000,99999,999999,999999999,9999999999,999999999999,99999999999999,3333333333333333,555555555555555555555]
    
    tries.each { |x|
      print "size #{x} -> #{format_mb(x)}\n"
    }
    

    哪个产生,

    size 1 -> 1 b
    size 2 -> 2 b
    size 3 -> 3 b
    size 500 -> 500 b
    size 1000 -> 1000 b
    size 1024 -> 1024 b
    size 3000 -> 2.930 kb
    size 99999 -> 97.655 kb
    size 999999 -> 976.562 kb
    size 999999999 -> 953.674 mb
    size 9999999999 -> 9.313 gb
    size 999999999999 -> 931.323 gb
    size 99999999999999 -> 90.949 tb
    size 3333333333333333 -> 2.961 pb
    size 555555555555555555555 -> 481.868 eb
    

    【讨论】:

      猜你喜欢
      • 2012-02-17
      • 2010-10-05
      • 2010-10-08
      • 1970-01-01
      • 2013-03-17
      • 2013-02-01
      • 1970-01-01
      • 2016-04-08
      • 2019-02-18
      相关资源
      最近更新 更多