如何将字节转换为mbs,gbs

时间:2015-12-29 15:22:23

标签: ruby-on-rails ruby-on-rails-3

我正在尝试将字节数转换为千字节,兆字节.i生成了一个表,其中所有文件都带有name和filesize.but文件大小以字节为单位,我只想将长长的数字转换为mbs ,GBS。     这是show file的代码:

  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 

谢谢!

3 个答案:

答案 0 :(得分:1)

将字节转换为kilo / mega / giga / tera字节的最简单方法是:

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

答案 1 :(得分:0)

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

class Filesize
  include Comparable

  TYPE_PREFIXES = {
    # Unit prefixes used for SI file sizes.
    :SI => %w{k M G T P E Z Y},
    # Unit prefixes used for binary file sizes.
    :BINARY => %w{Ki 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

答案 2 :(得分:0)

这是我对字节的解决方案:

  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} #{char}B"
      end
    end
  end

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