如何将字节转换为mbs,gbs

Posted

技术标签:

【中文标题】如何将字节转换为mbs,gbs【英文标题】:how to convert bytes into mbs,gbs 【发布时间】:2015-12-29 15:22:22 【问题描述】:

我正在尝试将字节数转换为千字节,兆字节。我生成了一个表格,其中所有文件都带有名称和文件大小。但文件大小以字节为单位,我只想将长数字转换为 mbs , 英镑。 这是显示文件的代码:

  for file in files[1]
            if file[1][:size] == nil
                filesize = 0
            else
                filesize = file[1][:size]
            end
            data += [["#file[1][:name]", "#filesize.to_s(:human_size) Bytes"]]
        end

我在其中使用了 .to_s(:humansize) 函数,因此遇到此错误

    can't convert Symbol into Integer 

谢谢!

【问题讨论】:

在这里回答了类似的问题***.com/questions/16026048/pretty-file-size-in-ruby 但我想在没有任何宝石的情况下这样做。 对于您遇到的错误 - 我查看了 to_s 的文档,它需要一个整数(这是将转换成的数字系统的基础)。可能这就是为什么您收到错误的原因:humansize 是一个符号,它没有被转换为整数。并且要将字节转换为 KB、GB 等,也许您可​​以参考@madyrockss 在评论中发布的问题的答案,这可能会对您有所帮助。 【参考方案1】:

将字节转换为千/兆/千兆/兆字节的最简单方法是:

def human_size size, kind
   c =  kilo: 1, mega: 2, giga: 3, tera: 4 [kind]
   human_size = size.to_f / 2**(10*c)
end

所以

human_size(1024, :kilo)
# => 1.0 
human_size(1024*1024, :mega)
# => 1.0 
human_size(1024*1024*1024, :giga)
# => 1.0 

human_size(file[1][:size], :giga) # returns size in gbs

【讨论】:

我在我的控制器中使用了这个方法,并在显示文件中调用了这个方法,比如 data += [["#file[1][:name]", "#filesize.human_size(文件[1][:size], :giga) 字节"]]【参考方案2】:

所以也许你可以看看madyrockss提到的宝石的来源:

class Filesize
  include Comparable

  TYPE_PREFIXES = 
    # Unit prefixes used for SI file sizes.
    :SI => %wk M G T P E Z Y,
    # Unit prefixes used for binary file sizes.
    :BINARY => %wKi Mi Gi Ti Pi Ei Zi Yi
  

  # @deprecated Please use TYPE_PREFIXES[:SI] instead
  PREFIXES = TYPE_PREFIXES[:SI]

  # Set of rules describing file sizes according to SI units.
  SI = 
    :regexp => /^([\d,.]+)?\s?([kmgtpezy]?)b$/i,
    :multiplier => 1000,
    :prefixes => TYPE_PREFIXES[:SI],
    :presuffix => '' # deprecated
  
  # Set of rules describing file sizes according to binary units.
  BINARY = 
    :regexp => /^([\d,.]+)?\s?(?:([kmgtpezy])i)?b$/i,
    :multiplier => 1024,
    :prefixes => TYPE_PREFIXES[:BINARY],
    :presuffix => 'i' # deprecated
  

  # @param [Number] size A file size, in bytes.
  # @param [SI, BINARY] type Which type to use for conversions.
  def initialize(size, type = BINARY)
    @bytes = size.to_i
    @type  = type
  end

  # @return [Number] Returns the size in bytes.
  def to_i
    @bytes
  end
  alias_method :to_int, :to_i

  # @param [String] unit Which unit to convert to.
  # @return [Float] Returns the size in a given unit.
  def to(unit = 'B')
    to_parts = self.class.parse(unit)
    prefix   = to_parts[:prefix]

    if prefix == 'B' or prefix.empty?
      return to_i.to_f
    end

    to_type = to_parts[:type]
    size    = @bytes

    pos = (@type[:prefixes].map  |s| s[0].chr.downcase .index(prefix.downcase) || -1) + 1

    size = size/(to_type[:multiplier].to_f**(pos)) unless pos < 1
  end
  alias_method :to_f, :to

  # @param (see #to_f)
  # @return [String] Same as #to_f, but as a string, with the unit appended.
  # @see #to_f
  def to_s(unit = 'B')
    "%.2f %s" % [to(unit).to_f.to_s, unit]
  end

  # Same as #to_s but with an automatic determination of the most
  # sensible unit.
  #
  # @return [String]
  # @see #to_s
  def pretty
    size = @bytes
    if size < @type[:multiplier]
      unit = "B"
    else
      pos = (Math.log(size) / Math.log(@type[:multiplier])).floor
      pos = @type[:prefixes].size-1 if pos > @type[:prefixes].size - 1

      unit = @type[:prefixes][pos-1] + "B"
    end

    to_s(unit)
  end

  # @return [Filesize]
  def +(other)
    self.class.new(@bytes + other.to_i, @type)
  end

  # @return [Filesize]
  def -(other)
    self.class.new(@bytes - other.to_i, @type)
  end

  # @return [Filesize]
  def *(other)
    self.class.new(@bytes * other.to_i, @type)
  end

  # @return [Filesize]
  def /(other)
    result = @bytes / other.to_f
    if other.is_a? Filesize
      result
    else
      self.class.new(result, @type)
    end
  end

  def <=>(other)
    self.to_i <=> other.to_i
  end

  # @return [Array<self, other>]
  # @api private
  def coerce(other)
    return self, other
  end

  class << self
    # Parses a string, which describes a file size, and returns a
    # Filesize object.
    #
    # @param [String] arg A file size to parse.
    # @raise [ArgumentError] Raised if the file size cannot be parsed properly.
    # @return [Filesize]
    def from(arg)
      parts  = parse(arg)
      prefix = parts[:prefix]
      size   = parts[:size]
      type   = parts[:type]

      raise ArgumentError, "Unparseable filesize" unless type

      offset = (type[:prefixes].map  |s| s[0].chr.downcase .index(prefix.downcase) || -1) + 1

      new(size * (type[:multiplier] ** (offset)), type)
    end

    # @return [Hash<:prefix, :size, :type>]
    # @api private
    def parse(string)
      type = nil
      # in this order, so we prefer binary :)
      [BINARY, SI].each  |_type|
        if string =~ _type[:regexp]
          type    =  _type
          break
        end
      

      prefix = $2 || ''
      size   = ($1 || 0).to_f

      return  :prefix => prefix, :size => size, :type => type
    end
  end

  # The size of a floppy disk
  Floppy = Filesize.from("1474 KiB")
  # The size of a CD
  CD     = Filesize.from("700 MB")
  # The size of a common DVD
  DVD_5  = Filesize.from("4.38 GiB")
  # The same as a DVD 5
  DVD    = DVD_5
  # The size of a single-sided dual-layer DVD
  DVD_9  = Filesize.from("7.92 GiB")
  # The size of a double-sided single-layer DVD
  DVD_10 = DVD_5 * 2
  # The size of a double-sided DVD, combining a DVD-9 and a DVD-5
  DVD_14 = DVD_9 + DVD_5
  # The size of a double-sided dual-layer DVD
  DVD_18 = DVD_14 * 2
  # The size of a Zip disk
  ZIP    = Filesize.from("100 MB")
end

参考:https://github.com/dominikh/filesize/blob/master/lib/filesize.rb

【讨论】:

【参考方案3】:

这是我的字节解决方案:

  BASE = 1000
  ROUND = 3
  EXP = 0 => '', 1 => 'k', 2 => 'M', 3 => 'G', 4 => 'T'
  def file_size_humanize(file_size)
    EXP.reverse_each do |exp, char|
      if (num = file_size.to_f / BASE**exp) >= 1
        rounded = num.round ROUND
        n = (rounded - rounded.to_i > 0) ? rounded : rounded.to_i
        return "#n #charB"
      end
    end
  end

对于位,您可以将 BASE 更改为 1024。

【讨论】:

以上是关于如何将字节转换为mbs,gbs的主要内容,如果未能解决你的问题,请参考以下文章

如何将数字转换为字节?

如何将 CString 转换为字节

我正在使用二进制阅读器将字符串转换为字节,如何将字节反转回相同的字符串 [重复]

如何将字节类型转换为字典?

如何将字节数组转换为字符串[重复]

如何将字节数组转换为流 [重复]