2
package Number::Bytes::Human;
10
our @ISA = qw(Exporter);
11
our @EXPORT_OK = qw(format_bytes);
14
use Carp qw(croak carp);
16
#my $DEFAULT_BLOCK = 1024;
17
#my $DEFAULT_ZERO = '0';
18
#my $DEFAULT_ROUND_STYLE = 'ceil';
19
my %DEFAULT_SUFFIXES = (
20
1024 => ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
21
1000 => ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
22
1024000 => ['', 'M', 'T', 'E', 'Y'],
23
si_1024 => ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'],
24
si_1000 => ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
26
my @DEFAULT_PREFIXES = @{$DEFAULT_SUFFIXES{1024}};
28
sub _default_suffixes {
29
my $set = shift || 1024;
30
if (exists $DEFAULT_SUFFIXES{$set}) {
31
return @{$DEFAULT_SUFFIXES{$set}} if wantarray;
32
return [ @{$DEFAULT_SUFFIXES{$set}} ];
34
croak "unknown suffix set '$set'";
37
my %ROUND_FUNCTIONS = (
38
ceil => \&POSIX::ceil,
39
floor => \&POSIX::floor,
40
#round => sub { shift }, # FIXME
41
#trunc => sub { int shift } # FIXME
43
# what about 'ceiling'?
48
if (exists $ROUND_FUNCTIONS{$style}) {
49
return $ROUND_FUNCTIONS{$style}
51
croak "unknown round style '$style'";
55
# block | block_size | base | bs => 1024 | 1000
56
# base_1024 | block_1024 | 1024 => $true
57
# base_1000 | block_1000 | 1000 => $true
59
# round_function => \&
60
# round_style => 'ceiling', 'round', 'floor', 'trunc'
62
# suffixes => 1024 | 1000 | si_1024 | si_1000 | 1024000 | \@
64
# unit => string (eg., 'B' | 'bps' | 'b')
66
# zero => '0' (default) | '-' | '0%S' | undef
69
# supress_point_zero | no_point_zero =>
73
# allow_minus => 0 | 1
75
# quiet => 1 (supresses "too large number" warning)
83
# BLOCK => 1024 | 1020
84
# ROUND_STYLE => 'ceil', 'round', 'floor', 'trunc'
85
# ROUND_FUNCTION => \&
92
$options = _parse_args($seed, $args)
93
$options = _parse_args($seed, arg1 => $val1, ...)
95
$seed is undef or a hashref
107
unless (defined $seed) { # use defaults
108
$options{BLOCK} = 1024;
109
$options{ROUND_STYLE} = 'ceil';
110
$options{ROUND_FUNCTION} = _round_function($options{ROUND_STYLE});
111
$options{ZERO} = '0';
112
#$options{SUFFIXES} = # deferred to the last minute when we know BLOCK, seek [**]
114
# else { %options = %$seed } # this is set if @_!=0, down below
116
if (@_==0) { # quick return for default values (no customized args)
117
return (defined $seed) ? $seed : \%options;
118
} elsif (@_==1 && ref $_[0]) { # \%args
120
} else { # arg1 => $val1, arg2 => $val2
124
# this is done here so this assignment/copy doesn't happen if @_==0
125
%options = %$seed unless %options;
127
# block | block_size | base | bs => 1024 | 1000
128
# block_1024 | base_1024 | 1024 => $true
129
# block_1000 | base_1000 | 1024 => $true
135
my $block = $args{block} ||
139
unless ($block==1000 || $block==1024 || $block==1_024_000) {
140
croak "invalid base: $block (should be 1024, 1000 or 1024000)";
142
$options{BLOCK} = $block;
144
} elsif ($args{block_1024} ||
148
$options{BLOCK} = 1024;
149
} elsif ($args{block_1000} ||
153
$options{BLOCK} = 1000;
156
# round_function => \&
157
# round_style => 'ceil' | 'floor' | 'round' | 'trunc'
158
if ($args{round_function}) {
159
unless (ref $args{round_function} eq 'CODE') {
160
croak "round function ($args{round_function}) should be a code ref";
162
$options{ROUND_FUNCTION} = $args{round_function};
163
$options{ROUND_STYLE} = $args{round_style} || 'unknown';
164
} elsif ($args{round_style}) {
165
$options{ROUND_FUNCTION} = _round_function($args{round_style});
166
$options{ROUND_STYLE} = $args{round_style};
169
# suffixes => 1024 | 1000 | si_1024 | si_1000 | 1024000 | \@
170
if ($args{suffixes}) {
171
if (ref $args{suffixes} eq 'ARRAY') {
172
$options{SUFFIXES} = $args{suffixes};
173
} elsif ($args{suffixes} =~ /^(si_)?(1000|1024)$/) {
174
$options{SUFFIXES} = _default_suffixes($args{suffixes});
176
croak "suffixes ($args{suffixes}) should be 1024, 1000, si_1024, si_1000, 1024000 or an array ref";
178
} elsif ($args{si}) {
179
my $set = ($options{BLOCK}==1024) ? 'si_1024' : 'si_1000';
180
$options{SUFFIXES} = _default_suffixes($set);
181
} elsif (defined $args{unit}) {
182
my $suff = $args{unit};
183
$options{SUFFIXES} = [ map { "$_$suff" } @DEFAULT_PREFIXES ];
186
# zero => undef | string
187
if (exists $args{zero}) {
188
$options{ZERO} = $args{zero};
189
if (defined $options{ZERO}) {
190
$options{ZERO} =~ s/%S/$options{SUFFIXES}->[0]/g
206
# NOTE. _format_bytes() SHOULD not change $options - NEVER.
210
return undef unless defined $bytes;
212
my %options = %$options;
214
local *human_round = $options{ROUND_FUNCTION};
216
return $options{ZERO} if ($bytes==0 && defined $options{ZERO});
218
my $block = $options{BLOCK};
220
# if a suffix set was not specified, pick a default [**]
221
my @suffixes = $options{SUFFIXES} ? @{$options{SUFFIXES}} : _default_suffixes($block);
223
# WHAT ABOUT NEGATIVE NUMBERS: -1K ?
229
return $sign . human_round($bytes) . $suffixes[0] if $bytes<$block;
231
# return "$sign$bytes" if $bytes<$block;
235
foreach (@suffixes) {
236
$suffix = $_, last if human_round($x) < $block;
239
unless (defined $suffix) { # number >= $block*($block**@suffixes) [>= 1E30, that's huge!]
240
unless ($options{QUIET}) {
241
my $pow = @suffixes+1;
242
carp "number too large (>= $block**$pow)"
244
$suffix = $suffixes[-1];
247
# OPTION: return "Inf"
251
$num = sprintf("%.1f", human_round($x*10)/10);
253
$num = sprintf("%d", human_round($x));
260
# convert byte count (file size) to human readable format
263
my $options = _parse_args(undef, @_);
264
#use YAML; print Dump $options;
265
return _format_bytes($bytes, $options);
273
my $class = ref $proto || $proto;
274
my $opts = _parse_args(undef, @_);
275
return bless $opts, $class;
281
return $self->_parse_args(@_);
288
return _format_bytes($bytes, $self);
292
# the solution by COG in Filesys::DiskUsage
293
# convert size to human readable format
295
# defined (my $size = shift) || return undef;
297
# $config->{human} || return $size;
298
# my $block = $config->{'Human-readable'} ? 1000 : 1024;
299
# my @args = qw/B K M G/;
301
# while (@args && $size > $block) {
306
# if ($config->{'truncate-readable'} > 0) {
307
# $size = sprintf("%.$config->{'truncate-readable'}f",$size);
313
# not exact: 1024 => 1024B instead of 1K
314
# not nicely formatted => 1.00 instead of 1K
322
Number::Bytes::Human - Convert byte count to human readable format
326
use Number::Bytes::Human qw(format_bytes);
327
$size = format_bytes(0); # '0'
328
$size = format_bytes(2*1024); # '2.0K'
330
$size = format_bytes(1_234_890, bs => 1000); # '1.3M'
331
$size = format_bytes(1E9, bs => 1000); # '1.0G'
334
$human = Number::Bytes::Human->new(bs => 1000, si => 1);
335
$size = $human->format(1E7); # '10MB'
336
$human->set_options(zero => '-');
337
$size = $human->format(0); # '-'
341
THIS IS ALPHA SOFTWARE: THE DOCUMENTATION AND THE CODE WILL SUFFER
342
CHANGES SOME DAY (THANKS, GOD!).
344
This module provides a formatter which turns byte counts
345
to usual readable format, like '2.0K', '3.1G', '100B'.
346
It was inspired in the C<-h> option of Unix
347
utilities like C<du>, C<df> and C<ls> for "human-readable" output.
349
From the FreeBSD man page of C<df>: http://www.freebsd.org/cgi/man.cgi?query=df
351
"Human-readable" output. Use unit suffixes: Byte, Kilobyte,
352
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
353
number of digits to four or fewer using base 2 for sizes.
356
kilobyte K = 2**10 B = 1024 B
357
megabyte M = 2**20 B = 1024 * 1024 B
358
gigabyte G = 2**30 B = 1024 * 1024 * 1024 B
359
terabyte T = 2**40 B = 1024 * 1024 * 1024 * 1024 B
361
petabyte P = 2**50 B = 1024 * 1024 * 1024 * 1024 * 1024 B
362
exabyte E = 2**60 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
363
zettabyte Z = 2**70 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
364
yottabyte Y = 2**80 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
366
I have found this link to be quite useful:
368
http://www.t1shopper.com/tools/calculate/
370
If you feel like a hard-drive manufacturer, you can start
371
counting bytes by powers of 1000 (instead of the generous 1024).
372
Just use C<< bs => 1000 >>.
374
But if you are a floppy disk manufacturer and want to start
375
counting in units of 1024000 (for your "1.44 MB" disks)?
376
Then use C<< bs => 1_024_000 >>.
378
If you feel like a purist academic, you can force the use of
380
according to the Dec 1998 standard by the IEC. Never mind the units for base 1000
381
are C<('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')> and,
382
even worse, the ones for base 1024 are
383
C<('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')>
384
with the horrible names: bytes, kibibytes, mebibytes, etc.
385
All you have to do is to use C<< si => 1 >>. Ain't that beautiful
386
the SI system? Read about it:
388
http://physics.nist.gov/cuu/Units/binary.html
390
You can try a pure Perl C<"ls -lh">-inspired command with the one-liner, er, two-liner:
392
$ perl -MNumber::Bytes::Human=format_bytes \
393
-e 'printf "%5s %s\n", format_bytes(-s), $_ for @ARGV' *
395
Why to write such a module? Because if people can write such things
396
in C, it can be written much easier in Perl and then reused,
397
refactored, abused. And then, when it is much improved, some
398
brave soul can port it back to C (if only for the warm feeling
399
of painful programming).
403
An alternative to the functional style of this module
404
is the OO fashion. This is useful for avoiding the
405
unnecessary parsing of the arguments over and over
406
if you have to format lots of numbers
410
my $fmt_size = format_bytes($_, @args);
416
my $human = Number::Format::Bytes->new(@args);
418
my $fmt_size = $human->format($_);
423
[TODO] MAKE IT JUST A MATTER OF STYLE: memoize _parse_args()
430
=item B<format_bytes>
432
$h_size = format_bytes($size, @options);
434
Turns a byte count (like 1230) to a readable format like '1.3K'.
435
You have a bunch of options to play with. See the section
436
L</"OPTIONS"> to know the details.
446
$h = Number::Bytes::Human->new(@options);
448
The constructor. For details on the arguments, see the section
453
$h_size = $h->format($size);
455
Turns a byte count (like 1230) to a readable format like '1.3K'.
458
$h = Number::Bytes::Human->new(@options);
459
$h_size = $h->format($size);
461
are equivalent to C<$h_size = format_bytes($size, @options)>,
462
with only one pass for the option arguments.
466
$h->set_options(@options);
468
To alter the options of a C<Number::Bytes::Human> object.
479
block | base | block_size | bs => 1000 | 1024 | 1024000
480
base_1024 | block_1024 | 1024 => 1
481
base_1000 | block_1000 | 1000 => 1
483
The base to be used: 1024 (default), 1000 or 1024000.
485
Any other value throws an exception.
489
suffixes => 1000 | 1024 | 1024000 | si_1000 | si_1024 | $arrayref
491
By default, the used suffixes stand for '', 'K', 'M', ...
492
for base 1024 and '', 'k', 'M', ... for base 1000
493
(which are indeed the usual metric prefixes with implied unit
494
as bytes, 'B'). For the weird 1024000 base, suffixes are
499
zero => string | undef
501
The string C<0> maps to ('0' by default). If C<undef>, the general case is used.
502
The string may contain '%S' in which case the suffix for byte is used.
504
format_bytes(0, zero => '-') => '-'
512
round_function => $coderef
513
round_style => 'ceil' | 'floor'
521
Suppresses the warnings emitted. Currently, the only case is
522
when the number is large than C<$base**(@suffixes+1)>.
528
It is alright to import C<format_bytes>, but nothing is exported by default.
532
"unknown round style '$style'";
534
"invalid base: $block (should be 1024, 1000 or 1024000)";
536
"round function ($args{round_function}) should be a code ref";
538
"suffixes ($args{suffixes}) should be 1000, 1024, 1024000 or an array ref";
540
"negative numbers are not allowed" (??)
544
A function C<parse_bytes>
546
parse_bytes($str, $options)
548
which transforms '1k' to 1000, '1K' to 1024, '1MB' to 1E6,
549
'1M' to 1024*1024, etc. (like gnu du).
551
$str =~ /^\s*(\d*\.?\d*)\s*(\S+)/ # $num $suffix
555
F<lib/human.c> and F<lib/human.h> in GNU coreutils.
557
The C<_convert()> solution by COG in Filesys::DiskUsage.
561
Please report bugs via CPAN RT L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Number-Bytes-Human>
562
or L<mailto://bug-Number-Bytes-Human@rt.cpan.org>. I will not be able to close the bug
563
as BestPractical ignore my claims that I cannot log in, but I will answer anyway.
567
Adriano R. Ferreira, E<lt>ferreira@cpan.orgE<gt>
569
=head1 COPYRIGHT AND LICENSE
571
Copyright (C) 2005-2007 by Adriano R. Ferreira
573
This library is free software; you can redistribute it and/or modify
574
it under the same terms as Perl itself.
1
package Number::Bytes::Human;
9
our @ISA = qw(Exporter);
10
our @EXPORT_OK = qw(format_bytes parse_bytes);
13
use Carp qw(croak carp);
15
#my $DEFAULT_BLOCK = 1024;
16
#my $DEFAULT_ZERO = '0';
17
#my $DEFAULT_ROUND_STYLE = 'ceil';
18
my %DEFAULT_SUFFIXES = (
19
1024 => ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
20
1000 => ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
21
1024000 => ['', 'M', 'T', 'E', 'Y'],
22
si_1024 => ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'],
23
si_1000 => ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
25
my @DEFAULT_PREFIXES = @{$DEFAULT_SUFFIXES{1024}};
27
sub _default_suffixes {
28
my $set = shift || 1024;
29
if (exists $DEFAULT_SUFFIXES{$set}) {
30
return @{$DEFAULT_SUFFIXES{$set}} if wantarray;
31
return [ @{$DEFAULT_SUFFIXES{$set}} ];
33
croak "unknown suffix set '$set'";
36
my %ROUND_FUNCTIONS = (
37
ceil => sub { return POSIX::ceil($_[0] * (10 ** $_[1])) / 10**$_[1]; },
38
floor => sub { return POSIX::floor($_[0] * (10 ** $_[1])) / 10**$_[1]; },
39
round => sub { return sprintf( "%." . ( $_[1] || 0 ) . "f", $_[0] ); },
40
trunc => sub { return sprintf( "%d", $_[0] * (10 ** $_[1])) / 10**$_[1]; },
41
# what about 'ceiling'?
46
if (exists $ROUND_FUNCTIONS{$style}) {
47
return $ROUND_FUNCTIONS{$style}
49
croak "unknown round style '$style'";
53
# block | block_size | base | bs => 1024 | 1000
54
# base_1024 | block_1024 | 1024 => $true
55
# base_1000 | block_1000 | 1000 => $true
57
# round_function => \&
58
# round_style => 'ceiling', 'round', 'floor', 'trunc'
60
# suffixes => 1024 | 1000 | si_1024 | si_1000 | 1024000 | \@
62
# unit => string (eg., 'B' | 'bps' | 'b')
64
# zero => '0' (default) | '-' | '0%S' | undef
67
# supress_point_zero | no_point_zero =>
71
# allow_minus => 0 | 1
73
# quiet => 1 (supresses "too large number" warning)
78
# precision => integer
81
# BLOCK => 1024 | 1000
82
# ROUND_STYLE => 'ceil', 'round', 'floor', 'trunc'
83
# ROUND_FUNCTION => \&
86
# SI => undef | 1 Parse SI compatible
91
$options = _parse_args($seed, $args)
92
$options = _parse_args($seed, arg1 => $val1, ...)
94
$seed is undef or a hashref
106
unless (defined $seed) { # use defaults
107
$options{BLOCK} = 1024;
108
$options{ROUND_STYLE} = 'ceil';
109
$options{ROUND_FUNCTION} = _round_function($options{ROUND_STYLE});
110
$options{ZERO} = '0';
111
$options{SI} = undef;
112
$options{PRECISION} = 1;
113
$options{PRECISION_CUTOFF} = 1;
114
#$options{SUFFIXES} = # deferred to the last minute when we know BLOCK, seek [**]
115
$options{UNIT} = undef;
117
# else { %options = %$seed } # this is set if @_!=0, down below
119
if (@_==0) { # quick return for default values (no customized args)
120
return (defined $seed) ? $seed : \%options;
121
} elsif (@_==1 && ref $_[0]) { # \%args
123
} else { # arg1 => $val1, arg2 => $val2
127
# this is done here so this assignment/copy doesn't happen if @_==0
128
%options = %$seed unless %options;
130
# block | block_size | base | bs => 1024 | 1000
131
# block_1024 | base_1024 | 1024 => $true
132
# block_1000 | base_1000 | 1024 => $true
138
my $block = $args{block} ||
142
unless ($block==1000 || $block==1024 || $block==1_024_000) {
143
croak "invalid base: $block (should be 1024, 1000 or 1024000)";
145
$options{BLOCK} = $block;
147
} elsif ($args{block_1024} ||
151
$options{BLOCK} = 1024;
152
} elsif ($args{block_1000} ||
156
$options{BLOCK} = 1000;
159
# round_function => \&
160
# round_style => 'ceil' | 'floor' | 'round' | 'trunc'
161
if ($args{round_function}) {
162
unless (ref $args{round_function} eq 'CODE') {
163
croak "round function ($args{round_function}) should be a code ref";
165
$options{ROUND_FUNCTION} = $args{round_function};
166
$options{ROUND_STYLE} = $args{round_style} || 'unknown';
167
} elsif ($args{round_style}) {
168
$options{ROUND_FUNCTION} = _round_function($args{round_style});
169
$options{ROUND_STYLE} = $args{round_style};
172
# SI compatibility (mostly for parsing)
177
# suffixes => 1024 | 1000 | si_1024 | si_1000 | 1024000 | \@
178
if ($args{suffixes}) {
179
if (ref $args{suffixes} eq 'ARRAY') {
180
$options{SUFFIXES} = $args{suffixes};
181
} elsif ($args{suffixes} =~ /^(si_)?(1000|1024)$/) {
182
$options{SUFFIXES} = _default_suffixes($args{suffixes});
184
croak "suffixes ($args{suffixes}) should be 1024, 1000, si_1024, si_1000, 1024000 or an array ref";
187
if (defined $args{unit}) {
188
$options{UNIT} = $args{unit};
191
# zero => undef | string
192
if (exists $args{zero}) {
193
$options{ZERO} = $args{zero};
194
if (defined $options{ZERO}) {
195
$options{ZERO} =~ s/%S/$options{SUFFIXES}->[0]/g
199
# precision => <integer>
200
if (exists $args{precision} and $args{precision} =~ /\A\d+\z/) {
201
$options{PRECISION} = $args{precision};
204
# precision_cutoff => <intenger>
205
if (exists $args{precision_cutoff} and ($args{precision_cutoff} =~ /\A\d+\z/ or $args{precision_cutoff} = '-1')) {
206
$options{PRECISION_CUTOFF} = $args{precision_cutoff};
221
# NOTE. _format_bytes() SHOULD not change $options - NEVER.
225
return undef unless defined $bytes;
227
my %options = %$options;
229
local *human_round = $options{ROUND_FUNCTION};
231
return $options{ZERO} if ($bytes==0 && defined $options{ZERO});
233
my $block = $options{BLOCK};
235
# if a suffix set was not specified, pick a default [**]
236
my @suffixes = $options{SUFFIXES} ? @{$options{SUFFIXES}} : _default_suffixes( ($options{SI} ? 'si_' : '') . $block);
238
# WHAT ABOUT NEGATIVE NUMBERS: -1K ?
245
my $suffix = $suffixes[0];
248
if($bytes >= $block) {
249
# return "$sign$bytes" if $bytes<$block;
253
} while ( human_round($x, $options{PRECISION}) >= $block );
254
if($magnitude >= (0 + @suffixes)) {
255
carp "number too large (>= $block**$magnitude)" unless ($options{QUIET});
257
$suffix = $suffixes[$magnitude];
259
#$x = human_round( $x, $options{PRECISION} );
261
$x = _precision_cutoff($x, $options);
262
#reasses encase the precision_cutoff caused the value to cross the block size
266
if($magnitude >= (0 + @suffixes)) {
267
carp "number too large (>= $block**$magnitude)" unless ($options{QUIET});
269
$suffix = $suffixes[$magnitude];
270
$x = _precision_cutoff($x, $options);
273
my $unit = $options{UNIT} || '';
275
return $sign . $x . $suffix . $unit;
279
sub _precision_cutoff {
282
my %options = %$options;
283
if ( $options{PRECISION_CUTOFF} != -1 and ( length( sprintf( "%d", $bytes ) ) > $options{PRECISION_CUTOFF} ) ) {
284
$bytes = sprintf( "%d", human_round( $bytes, 0 ) );
286
$bytes = sprintf( "%." . $options{PRECISION} . "f", human_round( $bytes, $options{PRECISION} ) );
294
my %options = %$options;
296
return 0 if( exists $options{ZERO} && ((!defined $options{ZERO} && !defined $human) || (defined $human && $human eq $options{ZERO})) );
297
return undef unless defined $human;
303
if( $options{SUFFIXES} ) {
305
foreach my $s (@{$options{SUFFIXES}}) {
306
$suffix_mult{$s} = $m;
307
$suffix_block{$s} = $options{BLOCK};
308
$m *= $suffix_block{$s};
311
if( !defined $options{SI} || $options{SI} == 1 ) {
312
# If SI compatibility has been set BLOCK is ignored as it is infered from the unit
314
foreach my $s (@{$DEFAULT_SUFFIXES{si_1000}}) {
315
$suffix_mult{$s} = $m;
316
$suffix_block{$s} = 1000;
317
$m *= $suffix_block{$s};
321
foreach my $s (@{$DEFAULT_SUFFIXES{si_1024}}) {
322
$suffix_mult{$s} = $m;
323
$suffix_block{$s} = 1024;
324
$m *= $suffix_block{$s};
328
# The regular suffixes are only taken into account in default mode without specifically asking for SI compliance
329
if( !defined $options{SI} ) {
331
foreach my $s (_default_suffixes( $options{BLOCK} )) {
332
$suffix_mult{$s} = $m;
333
$suffix_block{$s} = $options{BLOCK};
334
$m *= $suffix_block{$s};
339
my ($sign, $int, $frac, $unit) = ($human =~ /^\s*(-?)\s*(\d*)(?:\.(\d*))?\s*(\D*)$/);
343
# print STDERR "S: $sign I: $int F: $frac U: $unit\n";
348
my $u = $options{UNIT} || '';
349
foreach my $s (keys %suffix_block) {
350
if( $unit =~ /^${s}${u}$/i ) {
351
$mult = ($sign eq '-' ? -1 : 1) * $suffix_mult{$s};
352
$block = $suffix_block{$s};
357
if( !defined $mult ) {
358
carp "Could not parse human readable byte value '$human'";
360
print STDERR Dumper( %suffix_block );
364
my $bytes = int( ($int + ($frac / $block)) * $mult );
370
# convert byte count (file size) to human readable format
373
my $options = _parse_args(undef, @_);
374
#use YAML; print Dump $options;
375
return _format_bytes($bytes, $options);
378
# convert human readable format to byte count (file size)
381
my $options = _parse_args(undef, @_);
382
#use YAML; print Dump $options;
383
return _parse_bytes($human, $options);
391
my $class = ref $proto || $proto;
392
my $opts = _parse_args(undef, @_);
393
return bless $opts, $class;
399
return $self->_parse_args(@_);
406
return _format_bytes($bytes, $self);
413
return _parse_bytes($human, $self);
416
# the solution by COG in Filesys::DiskUsage
417
# convert size to human readable format
419
# defined (my $size = shift) || return undef;
421
# $config->{human} || return $size;
422
# my $block = $config->{'Human-readable'} ? 1000 : 1024;
423
# my @args = qw/B K M G/;
425
# while (@args && $size > $block) {
430
# if ($config->{'truncate-readable'} > 0) {
431
# $size = sprintf("%.$config->{'truncate-readable'}f",$size);
437
# not exact: 1024 => 1024B instead of 1K
438
# not nicely formatted => 1.00 instead of 1K
446
Number::Bytes::Human - Convert byte count to human readable format
450
use Number::Bytes::Human qw(format_bytes parse_bytes);
451
$size = format_bytes(0); # '0'
452
$size = format_bytes(2*1024); # '2.0K'
454
$size = format_bytes(1_234_890, bs => 1000); # '1.3M'
455
$size = format_bytes(1E9, bs => 1000); # '1.0G'
457
my $bytes = parse_bytes('1.0K'); # 1024
458
my $bytes = parse_bytes('1.0KB'); # 1000, SI unit
459
my $bytes = parse_bytes('1.0KiB'); # 1024, SI unit
462
$human = Number::Bytes::Human->new(bs => 1000, si => 1);
463
$size = $human->format(1E7); # '10MB'
465
$bytes = $human->parse('10MB'); # 10*1000*1000
466
$bytes = $human->parse('10MiB'); # 10*1024*1024
467
$bytes = $human->parse('10M'); # Error, no SI unit
469
$human->set_options(zero => '-');
470
$size = $human->format(0); # '-'
471
$bytes = $human->parse('-'); # 0
473
$human = Number::Bytes::Human->new(bs => 1000, round_style => 'round', precision => 2);
474
$size = $human->format(10240000); # '10.24MB'
478
THIS IS ALPHA SOFTWARE: THE DOCUMENTATION AND THE CODE WILL SUFFER
479
CHANGES SOME DAY (THANKS, GOD!).
481
This module provides a formatter which turns byte counts
482
to usual readable format, like '2.0K', '3.1G', '100B'.
483
It was inspired in the C<-h> option of Unix
484
utilities like C<du>, C<df> and C<ls> for "human-readable" output.
486
From the FreeBSD man page of C<df>: http://www.freebsd.org/cgi/man.cgi?query=df
488
"Human-readable" output. Use unit suffixes: Byte, Kilobyte,
489
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
490
number of digits to four or fewer using base 2 for sizes.
493
kilobyte K = 2**10 B = 1024 B
494
megabyte M = 2**20 B = 1024 * 1024 B
495
gigabyte G = 2**30 B = 1024 * 1024 * 1024 B
496
terabyte T = 2**40 B = 1024 * 1024 * 1024 * 1024 B
498
petabyte P = 2**50 B = 1024 * 1024 * 1024 * 1024 * 1024 B
499
exabyte E = 2**60 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
500
zettabyte Z = 2**70 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
501
yottabyte Y = 2**80 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
503
I have found this link to be quite useful:
505
http://www.t1shopper.com/tools/calculate/
507
If you feel like a hard-drive manufacturer, you can start
508
counting bytes by powers of 1000 (instead of the generous 1024).
509
Just use C<< bs => 1000 >>.
511
But if you are a floppy disk manufacturer and want to start
512
counting in units of 1024000 (for your "1.44 MB" disks)?
513
Then use C<< bs => 1_024_000 >>.
515
If you feel like a purist academic, you can force the use of
517
according to the Dec 1998 standard by the IEC. Never mind the units for base 1000
518
are C<('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')> and,
519
even worse, the ones for base 1024 are
520
C<('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')>
521
with the horrible names: bytes, kibibytes, mebibytes, etc.
522
All you have to do is to use C<< si => 1 >>. Ain't that beautiful
523
the SI system? Read about it:
525
http://physics.nist.gov/cuu/Units/binary.html
527
You can try a pure Perl C<"ls -lh">-inspired command with the one-liner, er, two-liner:
529
$ perl -MNumber::Bytes::Human=format_bytes \
530
-e 'printf "%5s %s\n", format_bytes(-s), $_ for @ARGV' *
532
Why to write such a module? Because if people can write such things
533
in C, it can be written much easier in Perl and then reused,
534
refactored, abused. And then, when it is much improved, some
535
brave soul can port it back to C (if only for the warm feeling
536
of painful programming).
538
It is also possible to parse human readable formatted bytes. The
539
automatic format detection recognizes SI units with the blocksizes
540
of 1000 and 1024 respectively and additionally the customary K / M / G etc. with
541
blocksize 1024. When si => 1 is added to the options only SI units
542
are recognized. Explicitly specifying a blocksize changes it
543
for all detected units.
547
An alternative to the functional style of this module
548
is the OO fashion. This is useful for avoiding the
549
unnecessary parsing of the arguments over and over
550
if you have to format lots of numbers
554
my $fmt_size = format_bytes($_, @args);
560
my $human = Number::Format::Bytes->new(@args);
562
my $fmt_size = $human->format($_);
567
[TODO] MAKE IT JUST A MATTER OF STYLE: memoize _parse_args()
574
=item B<format_bytes>
576
$h_size = format_bytes($size, @options);
578
Turns a byte count (like 1230) to a readable format like '1.3K'.
579
You have a bunch of options to play with. See the section
580
L</"OPTIONS"> to know the details.
584
$size = parse_bytes($h_size, @options);
586
Turns a human readable byte count into a number of the equivalent bytes.
596
$h = Number::Bytes::Human->new(@options);
598
The constructor. For details on the arguments, see the section
603
$h_size = $h->format($size);
605
Turns a byte count (like 1230) to a readable format like '1.3K'.
608
$h = Number::Bytes::Human->new(@options);
609
$h_size = $h->format($size);
611
are equivalent to C<$h_size = format_bytes($size, @options)>,
612
with only one pass for the option arguments.
616
$size = $h->parse($h_size)
618
Turns a human readable byte count into the number of bytes.
621
$h = Number::Bytes::Human->new(@options);
622
$size = $h->format($h_size);
624
are equivalent to C<$size = parse_bytes($h_size, @options)>,
625
with only one pass for the option arguments.
629
$h->set_options(@options);
631
To alter the options of a C<Number::Bytes::Human> object.
642
block | base | block_size | bs => 1000 | 1024 | 1024000
643
base_1024 | block_1024 | 1024 => 1
644
base_1000 | block_1000 | 1000 => 1
646
The base to be used: 1024 (default), 1000 or 1024000.
648
Any other value throws an exception.
652
suffixes => 1000 | 1024 | 1024000 | si_1000 | si_1024 | $arrayref
654
By default, the used suffixes stand for '', 'K', 'M', ...
655
for base 1024 and '', 'k', 'M', ... for base 1000
656
(which are indeed the usual metric prefixes with implied unit
657
as bytes, 'B'). For the weird 1024000 base, suffixes are
662
zero => string | undef
664
The string C<0> maps to ('0' by default). If C<undef>, the general case is used.
665
The string may contain '%S' in which case the suffix for byte is used.
667
format_bytes(0, zero => '-') => '-'
675
round_function => $coderef
676
round_style => 'ceil' | 'floor' | 'round' | 'trunc'
684
Suppresses the warnings emitted. Currently, the only case is
685
when the number is large than C<$base**(@suffixes+1)>.
689
precision => <integer>
692
sets the precicion of digits, only apropreacte for round_style 'round' or if you
693
want to accept it in as the second parameter to your custome round_function.
695
=item PRECISION_CUTOFF
697
precision_cutoff => <integer>
700
when the number of digits exceeds this number causes the precision to be cutoff
701
(was default behaviour in 0.07 and below)
707
It is alright to import C<format_bytes> and C<parse_bytes>, but nothing is exported by default.
711
"unknown round style '$style'";
713
"invalid base: $block (should be 1024, 1000 or 1024000)";
715
"round function ($args{round_function}) should be a code ref";
717
"suffixes ($args{suffixes}) should be 1000, 1024, 1024000 or an array ref";
719
"negative numbers are not allowed" (??)
723
A function C<parse_bytes>
725
parse_bytes($str, $options)
727
which transforms '1k' to 1000, '1K' to 1024, '1MB' to 1E6,
728
'1M' to 1024*1024, etc. (like gnu du).
730
$str =~ /^\s*(\d*\.?\d*)\s*(\S+)/ # $num $suffix
734
F<lib/human.c> and F<lib/human.h> in GNU coreutils.
736
The C<_convert()> solution by COG in Filesys::DiskUsage.
740
Please report bugs via CPAN RT L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Number-Bytes-Human>
741
or L<mailto://bug-Number-Bytes-Human@rt.cpan.org>. I will not be able to close the bug
742
as BestPractical ignore my claims that I cannot log in, but I will answer anyway.
746
Adriano R. Ferreira, E<lt>ferreira@cpan.orgE<gt>
748
=head1 COPYRIGHT AND LICENSE
750
Copyright (C) 2005-2007 by Adriano R. Ferreira
752
This library is free software; you can redistribute it and/or modify
753
it under the same terms as Perl itself.