Ruby on rails 如何将字节转换为mbs,gbs
我正在尝试将字节数转换为千字节,兆字节。我生成了一个表,其中所有文件都是以名称和文件大小获取的。但是文件大小是以字节为单位的,我只想将较长的数字转换为mbs,gbs。 这是显示文件的代码:Ruby on rails 如何将字节转换为mbs,gbs,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,我正在尝试将字节数转换为千字节,兆字节。我生成了一个表,其中所有文件都是以名称和文件大小获取的。但是文件大小是以字节为单位的,我只想将较长的数字转换为mbs,gbs。 这是显示文件的代码: for file in files[1] if file[1][:size] == nil filesize = 0 else filesize = file[1][:size]
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
谢谢 那么,也许你可以看看马蒂洛克斯提到的宝石的来源:
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
类文件大小
包括可比
类型\前缀={
#用于SI文件大小的单位前缀。
:SI=>%w{k M G T P E Z Y},
#用于二进制文件大小的单位前缀。
:BINARY=>%w{Ki Mi Gi Ti Pi Ei Zi Yi}
}
#@已弃用,请改用类型前缀[:SI]
前缀=类型_前缀[:SI]
#根据国际单位制描述文件大小的一组规则。
SI={
:regexp=>/^([\d,.]+)?\s?([kmgtpezy]?)b$/i,
:乘数=>1000,
:prefixes=>TYPE_前缀[:SI],
:PRESCFFIX=>''已弃用
}
#根据二进制单位描述文件大小的一组规则。
二进制={
:regexp=>/^([\d,.]+)?\s?(?:([kmgtpezy])i)?b$/i,
:乘数=>1024,
:prefixes=>TYPE_前缀[:BINARY],
:preffix=>“i”#已弃用
}
#@param[Number]size文件大小,以字节为单位。
#@param[SI,BINARY]类型用于转换的类型。
def初始化(大小、类型=二进制)
@字节=size.to_i
@类型=类型
结束
#@return[Number]返回字节大小。
def to_i
@字节
结束
别名_方法:to_int,:to_i
#@param[String]要转换为的单位。
#@return[Float]返回给定单位的大小。
def to(单位为“B”)
to_parts=self.class.parse(单位)
prefix=到零件[:prefix]
如果prefix='B'或prefix.empty?
返回i到f
结束
to_type=to_parts[:type]
大小=@字节
pos=(@type[:prefixes].map{s|s[0].chr.downcase}.index(prefix.downcase)| |-1)+1
大小=大小/(到类型[:乘数]。到**(位置)),除非位置小于1
结束
别名\u方法:to\u f,:to
#@param(见#至(f))
#@return[String]与{#to_f}相同,但作为字符串,附加了单位。
#@see#to#f
def至_s(单位='B')
“%.2f%s”%[至(单位)。至(单位)
结束
#与{#to_s}相同,但自动确定最大
#敏感单位。
#
#@return[String]
#@see#to#s
漂亮的
大小=@字节
如果大小<@类型[:乘数]
unit=“B”
其他的
pos=(Math.log(大小)/Math.log(@type[:乘数]).floor
pos=@type[:prefixes]。如果pos>@type[:prefixes],则大小为-1。大小为-1
单位=@type[:前缀][pos-1]+“B”
结束
收件人(单位)
结束
#@return[Filesize]
def+(其他)
self.class.new(@bytes+other.to_i,@type)
结束
#@return[Filesize]
def-(其他)
self.class.new(@bytes-other.to_i,@type)
结束
#@return[Filesize]
def*(其他)
self.class.new(@bytes*other.to_i,@type)
结束
#@return[Filesize]
def/(其他)
结果=@bytes/other.to\u f
如果另一个是a?文件大小
结果
其他的
self.class.new(结果,@type)
结束
结束
def(其他)
自我对他人
结束
#@return[Array]
#@api private
def强制(其他)
回归自我,回归他者
结束
类前缀,:size=>size,:type=>type}
结束
结束
#软盘的大小
软盘=文件大小。从(“1474 KiB”)
#一张CD的大小
CD=Filesize.from(“700 MB”)
#普通DVD的大小
DVD_5=文件大小。从(“4.38 GiB”)
#与DVD 5相同
DVD=DVD_5
#单面双层DVD的大小
DVD_9=Filesize.from(“7.92 GiB”)
#双面单层DVD的大小
DVD_10=DVD_5*2
#双面DVD的大小,结合DVD-9和DVD-5
DVD_14=DVD_9+DVD_5
#双面双层DVD的大小
DVD_18=DVD_14*2
#压缩磁盘的大小
ZIP=Filesize.from(“100 MB”)
结束
参考资料:将字节转换为千/兆/千兆/兆字节的最简单方法是:
def human_size size, kind
c = { kilo: 1, mega: 2, giga: 3, tera: 4 }[kind]
human_size = size.to_f / 2**(10*c)
end
所以
下面是我的字节解决方案:
BASE=1000
轮=3
EXP={0=>'',1=>'k',2=>'M',3=>'G',4=>'T'}
def文件大小人性化(文件大小)
EXP.reverse|u每个do|EXP,char|
如果(num=file\u size.to\u f/BASE**exp)>=1
舍入=num.round
n=(四舍五入-四舍五入到_i>0)?四舍五入:四舍五入
返回“#{n}{char}B”
结束
结束
结束
对于位,您可以将基数更改为1024。这里回答了类似的问题,但我想在没有任何gem的情况下执行此操作。对于您遇到的错误,我查看了to_s的文档,它采用了一个整数(这是它将转换为的数字系统的基数)。这可能就是为什么您会得到这样的错误:humansize(一个符号)没有被转换为整数。若要将字节转换为KB、GB等,您可以参考@madyrockss在评论中发布的问题答案,这可能会对您有所帮助。我在控制器中使用了此方法,并在show file中调用了此方法,如data+=[[“{file[1][:name]}”,“#{filesize.human_size(file[1][:size],:giga)}bytes]]
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