Class: Filesize

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/filesize.rb

Constant Summary collapse

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}
}
PREFIXES =
Deprecated.

Please use TYPE_PREFIXES instead

TYPE_PREFIXES[:SI]
SI =

Set of rules describing file sizes according to SI units.

{
  :regexp => /^([\d,.]+)?[[:space:]]?([kmgtpezy]?)b?$/i,
  :multiplier => 1000,
  :prefixes => TYPE_PREFIXES[:SI],
  :presuffix => '' # deprecated
}
BINARY =

Set of rules describing file sizes according to binary units.

{
  :regexp => /^([\d,.]+)?[[:space:]]?(?:([kmgtpezy])i)?b?$/i,
  :multiplier => 1024,
  :prefixes => TYPE_PREFIXES[:BINARY],
  :presuffix => 'i' # deprecated
}
PRECISION =

Set default precision

2
Floppy =

The size of a floppy disk

Filesize.from("1474 KiB")
CD =

The size of a CD

Filesize.from("700 MB")
DVD_5 =

The size of a common DVD

Filesize.from("4.38 GiB")
DVD =

The same as a DVD 5

DVD_5
DVD_9 =

The size of a single-sided dual-layer DVD

Filesize.from("7.92 GiB")
DVD_10 =

The size of a double-sided single-layer DVD

DVD_5 * 2
DVD_14 =

The size of a double-sided DVD, combining a DVD-9 and a DVD-5

DVD_9 + DVD_5
DVD_18 =

The size of a double-sided dual-layer DVD

DVD_14 * 2
ZIP =

The size of a Zip disk

Filesize.from("100 MB")

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size, type = BINARY) ⇒ Filesize



34
35
36
37
# File 'lib/filesize.rb', line 34

def initialize(size, type = BINARY)
  @bytes = size.to_i
  @type  = type
end

Class Method Details

.from(arg) ⇒ Filesize

Parses a string, which describes a file size, and returns a Filesize object.

Raises:

  • (ArgumentError)

    Raised if the file size cannot be parsed properly.



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/filesize.rb', line 134

def from(arg)
  parts  = parse(arg)
  prefix = parts[:prefix]
  size   = parts[:size]
  type   = parts[:type]

  raise ArgumentError, "Unparseable filesize: #{arg}" unless type

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

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

.parse(string) ⇒ Hash<:prefix, :size, :type>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/filesize.rb', line 149

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

Instance Method Details

#*(other) ⇒ Filesize



103
104
105
# File 'lib/filesize.rb', line 103

def *(other)
  self.class.new(@bytes * other.to_i, @type)
end

#+(other) ⇒ Filesize



93
94
95
# File 'lib/filesize.rb', line 93

def +(other)
  self.class.new(@bytes + other.to_i, @type)
end

#-(other) ⇒ Filesize



98
99
100
# File 'lib/filesize.rb', line 98

def -(other)
  self.class.new(@bytes - other.to_i, @type)
end

#/(other) ⇒ Filesize



108
109
110
111
112
113
114
115
# File 'lib/filesize.rb', line 108

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

#<=>(other) ⇒ Object



117
118
119
# File 'lib/filesize.rb', line 117

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

#coerce(other) ⇒ Array<self, other>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



123
124
125
# File 'lib/filesize.rb', line 123

def coerce(other)
  return self, other
end

#pretty(args = {}) ⇒ String

Same as #to_s but with an automatic determination of the most sensible unit.

See Also:



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/filesize.rb', line 78

def pretty(args = {})
  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, args)
end

#to(unit = 'B') ⇒ Float Also known as: to_f



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/filesize.rb', line 47

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

#to_iNumber Also known as: to_int



40
41
42
# File 'lib/filesize.rb', line 40

def to_i
  @bytes
end

#to_s(unit = 'B', args = {}) ⇒ String

Returns Same as #to_f, but as a string, with the unit appended.

See Also:



67
68
69
70
71
# File 'lib/filesize.rb', line 67

def to_s(unit = 'B', args = {})
  precision = args[:precision] || PRECISION
  
  "%.#{precision}f %s" % [to(unit).to_f.to_s, unit]
end