HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Printing human-readable number of bytes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
humannumberreadableprintingbytes

Problem

def as_size( s )
  prefix = %W(TiB GiB MiB KiB B)
  s = s.to_f
  i = prefix.length - 1
  while s > 512 && i > 0
    s /= 1024
    i -= 1
  end
  ("%#{s > 9 ? 'd' : '.1f'} #{prefix[i]}" % s).gsub /\.0/, ''
end


I'd like a clean and fast code to convert raw file size to human-readable format. Any hints?

Update (faster format):

def as_size( s )
  prefix = %W(TiB GiB MiB KiB B)
  s = s.to_f
  i = prefix.length - 1
  while s > 512 && i > 0
    s /= 1024
    i -= 1
  end
  ((s > 9 || s.modulo(1) < 0.1 ? '%d' : '%.1f') % s) + ' ' + prefix[i]
end


Update (freeze the constant):

PREFIX = %W(TiB GiB MiB KiB B).freeze

def as_size( s )
  s = s.to_f
  i = PREFIX.length - 1
  while s > 512 && i > 0
    i -= 1
    s /= 1024
  end
  ((s > 9 || s.modulo(1) < 0.1 ? '%d' : '%.1f') % s) + ' ' + PREFIX[i]
end

Solution

Possible solution: reduce your input to required precision. Returned result construction also reads cleaner with this approach:

def as_size(s)
  units = %W(B KiB MiB GiB TiB)

  size, unit = units.reduce(s.to_f) do |(fsize, _), utype|
    fsize > 512 ? [fsize / 1024, utype] : (break [fsize, utype])
  end

  "#{size > 9 || size.modulo(1) < 0.1 ? '%d' : '%.1f'} %s" % [size, unit]
end

Code Snippets

def as_size(s)
  units = %W(B KiB MiB GiB TiB)

  size, unit = units.reduce(s.to_f) do |(fsize, _), utype|
    fsize > 512 ? [fsize / 1024, utype] : (break [fsize, utype])
  end

  "#{size > 9 || size.modulo(1) < 0.1 ? '%d' : '%.1f'} %s" % [size, unit]
end

Context

StackExchange Code Review Q#9107, answer score: 5

Revisions (0)

No revisions yet.