如何将字节转换为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的主要内容,如果未能解决你的问题,请参考以下文章