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

Returns a new instance of Filesize.

Parameters:

  • size (Number)

    A file size, in bytes.

  • type (SI, BINARY) (defaults to: BINARY)

    Which type to use for conversions.



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.

Parameters:

  • arg (String)

    A file size to parse.

Returns:

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.

Returns:

  • (Hash<:prefix, :size, :type>)


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

Returns:



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

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

#+(other) ⇒ Filesize

Returns:



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

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

#-(other) ⇒ Filesize

Returns:



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

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

#/(other) ⇒ Filesize

Returns:



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.

Returns:

  • (Array<self, other>)


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.

Returns:

  • (String)

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

Returns the size in a given unit.

Parameters:

  • unit (String) (defaults to: 'B')

    Which unit to convert to.

Returns:

  • (Float)

    Returns the size in a given unit.



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

Returns the size in bytes.

Returns:

  • (Number)

    Returns the size in bytes.



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.

Parameters:

  • unit (String) (defaults to: 'B')

    Which unit to convert to.

Returns:

  • (String)

    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