File Coverage

blib/lib/File/Size.pm
Criterion Covered Total %
statement 20 50 40.0
branch 0 4 0.0
condition 0 15 0.0
subroutine 7 15 46.6
pod 6 6 100.0
total 33 90 36.6


line stmt bran cond sub pod time code
1             package File::Size;
2              
3 1     1   4617 use 5.006;
  1         9  
4 1     1   5 use warnings;
  1         1  
  1         31  
5 1     1   5 use strict;
  1         1  
  1         17  
6 1     1   4 use File::Find;
  1         2  
  1         63  
7 1     1   5 use Cwd;
  1         2  
  1         55  
8 1     1   435 use Number::Bytes::Human qw( format_bytes );
  1         9520  
  1         51  
9 1     1   5 no warnings 'File::Find';
  1         2  
  1         362  
10             our $VERSION = '0.06';
11              
12             =pod
13              
14             =head1 NAME
15              
16             File::Size - Get the size of files and directories
17              
18             =head1 SYNOPSIS
19              
20             Get the size for directory /etc/ with the block size of 1024 while following symbolic links:
21              
22             my $obj = File::Size->new(
23             dir => '/etc/',
24             blocksize => 1024,
25             followsymlinks => 1,
26             humanreadable => 1
27             );
28             print $obj->getsize(), "\n";
29              
30             =head1 DESCRIPTION
31              
32             File::Size is used to get the size of files and directories.
33              
34             There are 6 methods you can use:
35              
36             =over 6
37              
38             =item B
39              
40             There are 4 optional hash values for the new() method:
41              
42             =over 4
43              
44             =item C
45              
46             The directory you want the module to get the size for it. Default is current working directory.
47              
48             =item C
49              
50             The blocksize for the output of getsize() method. default is 1 (output in bytes).
51              
52             =item C
53              
54             If you want to follow symlinks for directories and files, use this option. The default is not to follow symlinks.
55              
56             =item C
57              
58             If you want output size in human readable format (e.g. 2048 -> 2.0K), set this option to 1.
59              
60             =back
61              
62             You don't have to specify any of those options, which means this is okay:
63             print File::Size->new()->getsize(), " bytes\n";
64             This is okay too:
65             print File::Size->new()->setdir( '/etc/' )->setblocksize( 1024**2 )->getsize(), " MB\n";
66              
67             =item B
68              
69             Used to set (or get - if called without parameters) the directory.
70             Example:
71             $obj->setdir( '/etc/' );
72              
73             =item B
74              
75             Used to set (or get - if called without parameters) the block size.
76             Example:
77             $obj->setblocksize( 1024 );
78              
79             =item B
80              
81             Used to set if you want to follow symbolic links or not. If called without parmeters, returns the current state.
82             Example:
83             $obj->setfollowsymlinks( 1 );
84              
85             =item B
86              
87             Used to set (or get - if called without parameters) if you want human-readable output sizes.
88             Example:
89             $obj->sethumanreadable( 1 );
90              
91             =item B
92              
93             Used to calculate the total size of the directory. Prints output according to the block size you did or didn't specify.
94              
95             =back
96              
97             =cut
98              
99             my $followsymlinks = 0;
100             my $blocksize = 0;
101             my $size = 0;
102              
103             sub new {
104 0     0 1   my $class = shift;
105 0           my %options = @_;
106 0           my $self = \%options;
107 0           bless( $self, $class );
108 0           return $self;
109             }
110              
111             sub DESTROY {
112 0     0     my $self = shift;
113 0           undef( $self );
114             }
115              
116             sub setdir {
117 0     0 1   my $self = shift;
118 0   0       $$self{ 'dir' } = shift || return $$self{ 'dir' };
119 0           return $self;
120             }
121              
122             sub setblocksize {
123 0     0 1   my $self = shift;
124 0   0       $$self{ 'blocksize' } = shift || return $$self{ 'blocksize' };
125 0           return $self;
126             }
127              
128             sub setfollowsymlinks {
129 0     0 1   my $self = shift;
130 0   0       $$self{ 'followsymlinks' } = shift || return $$self{ 'followsymlinks' };
131 0           return $self;
132             }
133              
134             sub sethumanreadable {
135 0     0 1   my $self = shift;
136 0   0       $$self{ 'humanreadable' } = shift || return $$self{ 'humanreadable' };
137 0           return $self;
138             }
139              
140             sub getsize {
141 0     0 1   my $self = shift;
142 0           my %options;
143 0 0         if ( $$self{ 'followsymlinks' } ) {
144 0           %options = (
145             wanted => \&_findcb,
146             follow => 1, # follow symlinks
147             follow_skip => 2 # skip duplicate links, but don't die doing it
148             );
149             } else {
150 0           %options = (
151             wanted => \&_findcb
152             );
153             }
154 0   0       my $dir = $$self{ 'dir' } || getcwd();
155 0   0       my $blocksize = $$self{ 'blocksize' } || 1;
156 0           $size = 0; # reset the size counter
157 0           find( \%options, $dir );
158 0 0         return $$self{ 'humanreadable' } ? format_bytes( $size ) : sprintf( '%d', $size / $blocksize );
159             }
160              
161             sub _findcb {
162 0   0 0     $size += -s $File::Find::name || 0;
163             }
164              
165             1;