logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

File::Util::Manual::Examples - File::Util Examples

Authors

Examples

       Many of these are demonstrated in the standalone scripts that come in the "examples" directory as part of
       this distribution.

       Unless indicated otherwise, all of these short examples assume that you have started out with:

          use File::Util;
          my $f = File::Util->new();

       The variable $f is used for simplicity here in the examples.  In your actual programming you should
       refrain from using single-letter variables and use something more obvious instead, such as $ftl or $futil

   Getthecontentsofafileinastring
          my $contents = $f->load_file( 'filename' );


             -OR-
          my $contents = $f->load_file( '/path/to/filename' );


             -OR-
          my $contents = $f->load_file( 'C:\path\to\filename' );

   GetthecontentsofaUTF-8encodedfileinaUTF-8encodedstring
          my $encoded_data = $f->load_file( 'encoded.txt' => { binmode => 'utf8' } );

   Getthecontentsofafileinanarrayoflinesinthefile
          my @contents = $f->load_file( 'filename' => { as_lines => 1 } );

   Getanopenfilehandleforreading
          my $fh = $f->open_handle(
             file => '/some/existing/file',
             mode => 'read'
          );


             -OR-
          # ... you can also use the shorter syntax:
          my $fh = $f->open_handle( '/some/existing/file' => 'read' );

          # ... you can open a file handle to a UTF-8 encoded file too
          my $fh = $f->open_handle( 'encoded.txt' => 'read' => { binmode => 'utf8' } );

          # then use the filehandle like you would use any other file handle:
          while ( my $line = <$fh> ) {

             # ... do stuff with $line
          }

          close $fh or die $!;

   Getanopenfilehandleforwriting
       Opening a file for writing (write mode) will create the file if it doesn't already exist.  The file
       handle is automatically locked for you with flock() if your system supports it.

          my $fh = $f->open_handle(
             file => '/some/file',
             mode => 'write'
          );


             -OR-
          # ... you can also use the shorter syntax:
          my $fh = $f->open_handle( '/some/file' => 'write' );

          # ... you can open a file handle with UTF-8 encoding support
          my $fh = $f->open_handle( '/some/file' => 'write' => { binmode => 'utf8' } );

          print $fh 'Hello world!';

          close $fh or die $!;

   Writetoaneworexistingfile
          my $content = 'Pathelogically Eclectic Rubbish Lister';

          $f->write_file( file => 'a new file.txt', content => $content );


             -OR-
          # you can use the shorter syntax:
          $f->write_file( 'a new file.txt' => $content );


             -OR-
          # write UTF-8 encoded data also.  the file will have UTF-8 encoding:
          $f->write_file( 'encoded.txt' => $encoded_data => { binmode => 'utf8' } );

       You can optionally specify a bitmask for a file if it doesn't exist yet.  The bitmask is combined with
       the user's current umask for the creation mode of the file.  (You should usually omit this.)

          $f->write_file(
             file    => 'C:\some\new\file.txt',
             content => $content
             bitmask => oct 777,
          );


             -OR-
          $f->write_file( 'file.txt' => $content => { bitmask => oct 777 } );

   Warnifthefilecouldn'tbewritten,insteadofdyingbydefault
          $f->write_file(
             'file.txt' => $content,
             {
                onfail  => 'warn',
                bitmask => oct 777
             }
          );

   Concealtheerrorifthefilecouldn'tbewritten(secure),butlogittoo
          # define a custom (secure) error handler

          $f->write_file(
             'file.txt' => $content =>
             {
                bitmask => oct 777
                onfail  => sub {
                   my ( $err, $stack ) = @_;

                   # send the error message and stack trace to a logger of some kind...
                   $logger->log( $err . $stack );

                   # or send an email alert?
                   send_email_alert_to_admin( $err ); #<< you'll have to write that sub

                   # return undef to indicate a problem (or you could die/exit too)
                   return;
                }
             }
          );

   Whynotfirstcheckifthefileiswriteable/canbecreated
          if ( $f->is_writable( '/root/some/file.txt' ) ) {

             # ... now create/write to the file
          }

   Appendtoaneworexistingfile
          my $content = 'The fastest hunk of junk in the galaxy';

          $f->write_file(
             file    => 'mfalcon.spec',
             mode    => 'append',
             content => $content
          );


             -OR-
          $f->write_file( 'mfalcon.spec' => $content => { mode => 'append' } );

   Getthenamesofallfilesandsubdirectoriesinadirectory
          # option no_fsdots excludes "." and ".." from the list
          my @dirs_and_files = $f->list_dir( '/foo' => { no_fsdots => 1 } );

   Getthenamesofallfilesandsubdirectoriesinadirectory,recursively
          my @dirs_and_files = $f->list_dir( '/foo' => { recurse => 1 } );

   Dothesameasabove,butonlytoacertainmaximumdepth
          my @dirs_and_files =
             $f->list_dir( '/foo' => { recurse => 1, max_depth => 3 } );

   Dothesame,butignorepotentialfilesystemloopsforaspeedboost
          my @dirs_and_files =
             $f->list_dir( '/foo' => { recurse_fast => 1, max_depth => 3 } );

   Getthenamesofallfiles(nosubdirectories)inadirectory
          my @dirs_and_files = $f->list_dir( '/foo' => { files_only => } );

   Getthenamesofallsubdirectories(nofiles)inadirectory
          my @dirs_and_files = $f->list_dir( '/foo' => { dirs_only => 1 } );

   Getthenumberoffilesandsubdirectoriesinadirectory
          my @dirs_and_files = $f->list_dir(
             '/foo' => { no_fsdots => 1, count_only => 1 }
          );

   Getthenamesoffilesandsubdirsinadirectoryasseparatearrayrefs
          my( $dirs, $files ) = $f->list_dir( '/foo' => { as_ref => 1 } );


             -OR-
          my( $dirs, $files ) = $f->list_dir(
             '/foo' => { dirs_as_ref => 1, files_as_ref => 1 }
          );

   Loadallthefilesinadirectoryintoahashref
          my $templates = $f->load_dir( '/var/www/mysite/templates' );

          # $templates now contains something like:
          # {
          #    'header.html' => '...file contents...',
          #    'body.html'   => '...file contents...',
          #    'footer.html' => '...file contents...',
          # }

          print $templates->{'header.html'};

   RecursivelyGetthenamesofallfilesthatendin'.pl'
          my @perl_files = $f->list_dir(
             '/home/scripts' => { files_match => qr/\.pl$/, recurse => 1 }
          }

   RecursivelygetthenamesofallfilesthatdoNOTendin'.pl'
       File::Util's "list_dir()" method doesn't have a "not_matches" counterpart to the "files_match" parameter.
       This is because it doesn't need one.  Perl already provides native support for negation in regular
       expressions.  The example below shows you how to make sure a file does NOT match the pattern you provide
       as a subexpression in a "negative zero width assertion".

       It might sound complicated for a beginner, but it's really not that hard.

       See the perlre documentation for more about negation in regular expressions.

          # find all files that don't end in ".pl"
          my @other_files = $f->list_dir(
             '/home/scripts' => { files_match => qr/^(?!.*\.pl$)/, recurse => 1 }
          }

   Combineseveraloptionsforlist_dir()andbeawesome
       Find all files (not directories) that matches *any* number of given patterns (OR), whose parent directory
       matches *every* pattern in a list of given patterns (AND).  Also make sure that the path to the files
       matches a list of patterns (AND).

          # find the droids I'm looking for...
          my @files = $f->list_dir(
             '/home/anakin' => {
                files_match    => { or  => [ qr/droid/, qr/3p(o|O)$/i, qr/^R2/ },
                parent_matches => { and => [ qr/vader/i, qr/darth/i ] },
                path_matches   => { and => [ qr/obi-wan/i, qr/^(?!.*Qui-Gon)/ ] },
                recursive      => 1,
                files_only     => 1,
                max_depth      => 8,
             }
          );

       The above example would find and return files like:

          /home/anakin/mentors/obi-wan/villains/darth-vader/R2.png
          /home/anakin/mentors/obi-wan/villains/darth-vader/C3P0.dict
          /home/anakin/mentors/obi-wan/villains/darth-vader/my_droids.list

       But would not return files like:

          /home/anakin/mentors/Qui-Gon Jinn/villains/darth-vader/my_droids.list

   Useacallbacktodescendthrough(walk)adirectorytree
       This is a really powerful feature. Because File::Util::list_dir() is a higher order function, it can take
       other functions as arguments.  We often refer to these as "callbacks".

       Any time you specify a callback, File::Util will make sure it's first argument is the name if the
       directory it's in (recursion), and then the second and third arguments are listrefs.  The first is a list
       reference containing the names of all subdirectories, and the second list ref contains the names of all
       the files.

       Below is a very simple example that doesn't really do much other than demonstrate the syntax.  You can
       see more full-blown examples of callbacks in the File::Util::Cookbook

          # print all subdirectories under /home/larry/
          $f->list_dir(
             '/home/larry' => {
                callback => sub { print shift @_, "\n" },
                recurse  => 1,
             }
          }

   Getadirectorytreeinahierarchicalhashref
          my $tree = $f->list_dir( '/tmp' => { as_tree => 1, recurse => 1 } );

          Gives you a datastructure like:
          {
            '/' => {
                     '_DIR_PARENT_' => undef,
                     '_DIR_SELF_' => '/',
                     'tmp' => {
                                '_DIR_PARENT_' => '/',
                                '_DIR_SELF_' => '/tmp',
                                'hJMOsoGuEb' => {
                                                  '_DIR_PARENT_' => '/tmp',
                                                  '_DIR_SELF_' => '/tmp/hJMOsoGuEb',
                                                  'a.txt' => '/tmp/hJMOsoGuEb/a.txt',
                                                  'b.log' => '/tmp/hJMOsoGuEb/b.log',
                                                  'c.ini' => '/tmp/hJMOsoGuEb/c.ini',
                                                  'd.bat' => '/tmp/hJMOsoGuEb/d.bat',
                                                  'e.sh' => '/tmp/hJMOsoGuEb/e.sh',
                                                  'f.conf' => '/tmp/hJMOsoGuEb/f.conf',
                                                  'g.bin' => '/tmp/hJMOsoGuEb/g.bin',
                                                  'h.rc' => '/tmp/hJMOsoGuEb/h.rc',
                                                }
                              }
                   }
          }

       *You can add the "dirmeta" option, set to 0 (false), to remove the special entries "_DIR_PARENT_" and
       "_DIR_SELF_" from each subdirectory branch.

       Example:

          my $tree = $f->list_dir(
             '/tmp' => { as_tree => 1, dirmeta => 0, recurse => 1 }
          );

       *You can still combine the "as_tree" option with other options, such as the regex pattern matching
       options covered above, or options like "recurse", or "files_only".

       *You should be careful using this feature with very large directory trees, due to the memory it might
       consume.  Memory usage is generally low, but will grow when you use this feature for larger and larger
       directory trees.  Bear in mind that the $ABORT_DEPTH limit applies here too (see File::Util
       documentation), which you can override manually by setting the "abort_depth" option:

          # set max recursion limit to an integer value as shown below
          $f->list_dir( '/tmp' => { as_tree => 1, recurse => 1, abort_depth => 123 } );

   Determineifsomethingisavalidfilename
       NOTE: This method is for determining if a filename  is valid.  It does not determine if a full path is
       valid.

          print $f->valid_filename( 'foo?+/bar~@/#baz.txt' ) ? 'ok' : 'bad';


             -OR-
          print File::Util->valid_filename( 'foo?+/bar~@/#baz.txt' ) ? 'ok' : 'bad';

       Like many other methods in File::Util, you can import this into your own namespace so you can call it
       like any other function, avoid the object-oriented syntax when you don't want or need it:  (This manual
       doesn't duplicate the main documentation by telling you every method you can import -- see the @EXPORT_OK
       section of the File::Util documentation)

          use File::Util qw( valid_filename );

          if ( valid_filename( 'foo?+/bar~@/#baz.txt' ) )
          {
             print 'file name is valid';
          }
          else
          {
             print 'That file name contains illegal characters';
          }

   Getthenumberoflinesinafile
          my $linecount = $f->line_count( 'foo.txt' );

   Splitafilepathintoitsparts
       This method works differently than atomize_path().  With this method, you get not just the components of
       the path, but each element in the form of a list.  The path will be split into the following pieces:
       (path root, if it exists, each subdirectory in the path, and the final file/directory )

          use File::Util qw( split_path );

          print "$_\n" for split_path( q{C:\foo\bar\baz\flarp.pl} )


             -OR-
          print "$_\n" for $f->split_path( q{C:\foo\bar\baz\flarp.pl} )


             -OR-
          print "$_\n" for File::Util->split_path( q{C:\foo\bar\baz\flarp.pl} )

          The output of all of the above commands is:
             C:\
             foo
             bar
             baz
             flarp.pl

       Above you see examples working on Windows-type paths.  Below are some examples using *nix-style paths:

          print "$_\n" for split_path( '/I/am/your/father/NOOOO' )

          The output of all of the above commands is:
             /
             I
             am
             your
             father
             NOOOO

   Stripthepathfromafilename
          # On Windows
          #  (prints "hosts")
          my $path = $f->strip_path( 'C:\WINDOWS\system32\drivers\etc\hosts' );

          # On Linux/Unix
          #  (prints "perl")
          print $f->strip_path( '/usr/bin/perl' );

          # On a Mac
          #  (prints "baz")
          print $f->strip_path( 'foo:bar:baz' );


             -OR-
          use File::Util qw( strip_path );

          print strip_path( '/some/file/name' ); # prints "name"

   Getthepathprecedingafilename
          # On Windows
          #  (prints "C:\WINDOWS\system32\drivers\etc")
          my $path = $f->return_path( 'C:\WINDOWS\system32\drivers\etc\hosts' );

          # On Linux/Unix
          #  (prints "/usr/bin")
          print $f->return_path( '/usr/bin/perl' );

          # On a (very, very old) Mac
          #  (prints "foo:bar")
          print $f->return_path( 'foo:bar:baz' );

   Findoutifthehostsystemcanuseflock
          use File::Util qw( can_flock );
          print can_flock;


             -OR-
          print File::Util->can_flock;


             -OR-
          print $f->can_flock;

   Findoutifthehostsystemneedstocallbinmodeonbinaryfiles
          use File::Util qw( needs_binmode );
          print needs_binmode;


             -OR-
          print File::Util->needs_binmode;


             -OR-
          print $f->needs_binmode;

   Findoutifafilecanbeopenedforread(basedonfilepermissions)
          my $is_readable = $f->is_readable( 'foo.txt' );

   Findoutifafilecanbeopenedforwrite(basedonfilepermissions)
          my $is_writable = $f->is_writable( 'foo.txt' );

   Escapeillegalcharactersinapotentialfilename(anditspath)
          # prints "C__WINDOWS_system32_drivers_etc_hosts"
          print $f->escape_filename( 'C:\WINDOWS\system32\drivers\etc\hosts' );

          # prints "baz)__@^"
          # (strips the file path from the file name, then escapes it
          print $f->escape_filename( '/foo/bar/baz)?*@^' => { strip_path => 1 } );

          # prints "_foo_!_@so~me#illegal$_file&(name"
          # (yes, technically that is a legal filename)
          print $f->escape_filename( q{\foo*!_@so~me#illegal$*file&(name} );

   FindoutifthehostsystemusesEBCDIC
          use File::Util qw( ebcdic );
          print ebcdic;


             -OR-
          print File::Util->ebcdic;


             -OR-
          print $f->ebcdic;

   Getthetype(s)ofanexistentfile
          use File::Util qw( file_type );
          print file_type( 'foo.exe' );


             -OR-
          print File::Util->file_type( 'bar.txt' );


             -OR-
          print $f->file_type( '/dev/null' );

   Getthebitmaskofanexistentfile
          use File::Util qw( bitmask );
          print bitmask( '/usr/sbin/sendmail' );


             -OR-
          print File::Util->bitmask( 'C:\COMMAND.COM' );


             -OR-
          print $f->bitmask( '/dev/null' );

   Gettimeofcreationforafile
          use File::Util qw( created );
          print scalar localtime created( '/usr/bin/exim' );


             -OR-
          print scalar localtime File::Util->created( 'C:\COMMAND.COM' );


             -OR-
          print scalar localtime $f->created( '/bin/less' );

   Getthelastaccesstimeforafile
          use File::Util qw( last_access );
          print scalar localtime last_access( '/usr/bin/exim' );


             -OR-
          print scalar localtime File::Util->last_access( 'C:\COMMAND.COM' );


             -OR-
          print scalar localtime $f->last_access( '/bin/less' );

   Gettheinodechangetimeforafile
          use File::Util qw( last_changed );
          print scalar localtime last_changed( '/usr/bin/vim' );


             -OR-
          print scalar localtime File::Util->last_changed( 'C:\COMMAND.COM' );


             -OR-
          print scalar localtime $f->last_changed( '/bin/cpio' );

   Getthelastmodifiedtimeforafile
          use File::Util qw( last_modified );
          print scalar localtime last_modified( '/usr/bin/exim' );


             -OR-
          print scalar localtime File::Util->last_modified( 'C:\COMMAND.COM' );


             -OR-
          print scalar localtime $f->last_modified( '/bin/less' );

   Makeanewdirectory,recursivelyifnecessary
          $f->make_dir( '/var/tmp/tempfiles/foo/bar/' );

          # you can optionally specify a bitmask for the new directory.
          # the bitmask is combined with the user's current umask for the creation
          # mode of the directory.  (You should usually omit this.)

          $f->make_dir( '/var/tmp/tempfiles/foo/bar/', 0755 );

   Touchafile
          use File::Util qw( touch );
          touch( 'somefile.txt' );


             -OR-
          $f->touch( '/foo/bar/baz.tmp' );

   Truncateafile
          $f->trunc( '/wibble/wombat/noot.tmp' );

   Getthecorrectpathseparatorforthehostsystem
          use File::Util qw( SL );
          print SL;


             -OR-
          print File::Util->SL;


             -OR-
          print $f->SL;

   Getthecorrectnewlinecharacterforthehostsystem
          use File::Util qw( NL );

          print NL;


             -OR-
          print File::Util->NL;


             -OR-
          print $f->NL;

   Choosewhattodoifthere'saproblem(die,warn,zero,undefined,subref)
          # When doing things with IO that might fail, set up good error handlers

          # "Fail, these examples will..."

          # If this call fails, die with an error message (*default*)
          $f->write_file( 'bobafett.txt' => $content => { onfail => 'die' } );

          # If this call fails, issue a warning to STDERR, but don't die/exit
          $f->list_dir( '/home/greivous' => { onfail => 'warn' } );

          # If this call fails, return a zero value (0), and don't die/exit
          $f->open_handle( '/home/ventress/.emacs' => { onfail => 'zero' } );

          # If this call fails, return undef, and don't die/exit
          $f->load_file( '/home/vader/darkside.manual' => { onfail => 'undefined' } );

          # If this call fails, execute the subroutine code and do whatever it says
          # This code tries to load one directory, and failing that, loads another
          $f->load_dir( '/home/palpatine/lofty_plans/' => {
                onfail => sub { return $f->load_dir( '/home/sidious/evil_plots/' ) }
             }
          );

Introduction

       This manual subsection is fully comprised of simple examples of File::Util in greater depth than what you
       see in the main documentation, however to keep things simple, these examples are short, quick, and to the
       point.

       For examples of full Programs using File::Util, take a look at the Cookbook at the File::Util::Cookbook.

License

       This library is free software, you may redistribute it and/or modify it under the same terms as Perl
       itself. For more details, see the full text of the LICENSE file that is included in this distribution.

Limitation Of Warranty

       This software is distributed in the hope that it will be useful, but without any warranty; without even
       the implied warranty of merchantability or fitness for a particular purpose.

Name

       File::Util::Manual::Examples - File::Util Examples

See Also

       File::Util::Manual, File::Util::Cookbook

perl v5.36.0                                       2022-11-29                  File::Util::Manual::Examples(3pm)

Version

       version 4.201720

See Also