File::Util - Easy, versatile, portable file handling
File::Util provides a comprehensive toolbox of utilities to automate all kinds of common tasks on file / directories. Its purpose is to do so in the most portable manner possible so that users of this module won't have to worry about whether their programs will work on other OSes and machines.
use File::Util; my $f = File::Util->new(); my $content = $f->load_file('foo.txt'); $content =~ s/this/that/g; $f->write_file( file => 'bar.txt', content => $content, bitmask => 0644 ); $f->write_file( file => 'file.bin', content => $binary_content, '--binmode' ); my @lines = $f->load_file('randomquote.txt', '--as-lines'); my $line = int rand scalar @lines; print $lines[ $line ]; my @files = $f->list_dir('/var/tmp', qw/ --files-only --recurse /); my @textfiles = $f->list_dir('/var/tmp', '--pattern=\.txt$'); if ( $f->can_write('wibble.log') ) { my $HANDLE = $f->open_handle( file => 'wibble.log', mode => 'append' ); print $HANDLE "Hello World! It's ", scalar localtime; close $HANDLE } my $log_line_count = $f->line_count('/var/log/httpd/access_log'); print "My file has a bitmask of " . $f->bitmask('my.file'); print "My file is a " . join(', ', $f->file_type('my.file')) . " file." warn 'This file is binary!' if $f->isbin('my.file'); print "My file was last modified on " . scalar localtime $f->last_modified('my.file'); # ...and _lots_ more
To install this module type the following at the command prompt:
perl Build.PL perl Build perl Build test sudo perl Build install
On Windows systems, the "sudo" part of the command may be omitted, but you will need to run the rest of the install command with Administrative privileges
Exports nothing by default. File::Util respects your namespace.
The following symbols comprise @File::Util::EXPORT_OK), and as such are available for import to your namespace only upon request.
@File::Util::EXPORT_OK
atomize_path (see atomize_path)
atomize_path
bitmask (see bitmask)
bitmask
can_flock (see can_flock)
can_flock
can_read (see can_read)
can_read
can_write (see can_write)
can_write
created (see created)
created
ebcdic (see ebcdic)
ebcdic
escape_filename (see escape_filename)
escape_filename
existent (see existent)
existent
file_type (see file_type)
file_type
isbin (see isbin)
isbin
last_access (see last_access)
last_access
last_changed (see last_changed)
last_changed
last_modified (see last_modified)
last_modified
NL (see NL)
NL
needs_binmode (see needs_binmode)
needs_binmode
return_path (see return_path)
return_path
size (see size)
size
SL (see SL)
SL
strip_path (see strip_path)
strip_path
valid_filename (see valid_filename)
valid_filename
Note: Symbols in @Class::OOorNO::EXPORT_OK are also available for import.
@Class::OOorNO::EXPORT_OK
:all (exports all of @File::Util::EXPORT_OK)
Note: In the past, some of the methods listed would state that they were autoloaded methods. This mechanism has been changed. Only the error handling and help messages are AutoLoad'ed now. (see AutoLoader.) if you want to know more about AutoLoading in Perl. See the CHANGES file distributed with File::Util for an explanation of why this change was made.
Methods listed in alphabetical order.
atomize_path( [file/path or file_name] )
This method is used internally by File::Util to portably handle absolute filenames on different platforms, but it can be a useful tool for you as well.
This method takes a single string as its argument. The string is expected to be a fully-qualified (absolute) or relative path to a file or directory. It carefully splits the string into three parts: The root of the path, the rest of the path, and the final file/directory named in the string.
Depending on the input, the root and/or path may be empty strings. The following table can serve as a guide in what to expect from atomize_path()
atomize_path()
+-------------------------+----------+--------------------+----------------+ | INPUT | ROOT | PATH-COMPONENT | FILE/DIR | +-------------------------+----------+--------------------+----------------+ | C:\foo\bar\baz.txt | C:\ | foo\bar | baz.txt | | /foo/bar/baz.txt | / | foo/bar | baz.txt | | ./a/b/c/d/e/f/g.txt | | ./a/b/c/d/e/f | g.txt | | :a:b:c:d:e:f:g.txt | : | a:b:c:d:e:f | g.txt | | ../wibble/wombat.ini | | ../wibble | wombat.ini | | ..\woot\noot.doc | | ..\woot | noot.doc | | ../../zoot.conf | | ../.. | zoot.conf | | /root | / | | root | | /etc/sudoers | / | etc | sudoers | | / | / | | | | D:\ | D:\ | | | | D:\autorun.inf | D:\ | | autorun.inf | +-------------------------+----------+--------------------+----------------+
bitmask( [file name] )
Gets the bitmask of the named file, provided the file exists. If the file exists, the bitmask of the named file is returned in four digit octal notation e.g.- 0644. Otherwise, returns undef if the file does not exist.
0644
undef
Returns 1 if the current system claims to support flock() and if the Perl process can successfully call it. (see "flock" in perlfunc.) Unless both of these conditions are true a zero value (0) is returned. This is a constant method. It accepts no arguments and will always return the same value for the system on which it is executed.
flock()
Note: Perl will try to support or emulate flock whenever it can via available system calls, namely flock; lockf; or with fcntl.
flock
lockf
fcntl
can_read( [file name] )
Returns 1 if the named file (or directory) is readable by your program according to the applied permissions of the file system on which the file resides. Otherwise a value of undef is returned.
This works the same as Perl's built-in -r file test operator, (see "-X" in perlfunc), it's just easier for some people to remember.
-r
can_write( [file name] )
Returns 1 if the named file (or directory) is writable by your program according to the applied permissions of the file system on which the file resides. Otherwise a value of undef is returned.
This works the same as Perl's built-in -w file test operator, (see "-X" in perlfunc), it's just easier for some people to remember.
-w
created( [file name] )
Returns the time of creation for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.)
Returns 1 if the machine on which the code is running uses EBCDIC, or returns 0 if not. (see perlebcdic.) This is a constant method. It accepts no arguments and will always return the same value for the system on which it is executed.
escape_filename( [string], [escape char] )
Returns it's argument in an escaped form that is suitable for use as a filename. Illegal characters (i.e.- any type of newline character, tab, vtab, and the following / | * " ? < : > \), are replaced with [escape char] or "_" if no [escape char] is specified. Returns an empty string if no arguments are provided.
/ | * " ? < : > \
existent( [file name] )
Returns 1 if the named file (or directory) exists. Otherwise a value of undef is returned.
This works the same as Perl's built-in -e file test operator, (see "-X" in perlfunc), it's just easier for some people to remember.
-e
file_type( [file name] )
Returns a list of keywords corresponding to each of Perl's built in file tests (those specific to file types) for which the named file returns true. (see "-X" in perlfunc.)
The keywords and their definitions appear below; the order of keywords returned is the same as the order in which the are listed here:
PLAIN File is a plain file.
TEXT File is a text file.
BINARY File is a binary file.
DIRECTORY File is a directory.
SYMLINK File is a symbolic link.
PIPE File is a named pipe (FIFO).
SOCKET File is a socket.
BLOCK File is a block special file.
CHARACTER File is a character special file.
flock_rules
flock_rules( [keyword list] )
Sets I/O race condition policy, or tells File::Util how it should handle race conditions created when a file can't be locked because it is already locked somewhere else (usually by another process).
An empty call to this method returns a list of keywords representing the rules that are currently in effect for the object.
Otherwise, a call should include a list with array containing your chosen directive keywords in order of precedence. The rules will be applied in cascading order when a File::Util object attempts to lock a file, so if the actions specified by the first rule don't result in success, the second rule is applied, and so on.
Recognized keywords:
NOBLOCKEX
tries to get an exclusive lock on the file without blocking (waiting)
NOBLOCKSH
tries to get a shared lock on the file without blocking
BLOCKEX
waits to try getting an exclusive lock
BLOCKSH
waits to try getting a shared lock
FAIL
dies with stack trace
WARN
warn()s about the error with a stack trace and returns undef
IGNORE
ignores the failure to get an exclusive lock
UNDEF
returns undef
ZERO
returns 0
Examples:
flock_rules( qw/ NOBLOCKEX FAIL / );
This is the default policy. When in effect, the File::Util object will first attempt to get a non-blocking exclusive lock on the file. If that attempt fails the File::Util object will call die() with a detailed error message and a stack trace.
flock_rules( qw/ NOBLOCKEX BLOCKEX FAIL / );
The File::Util object will first attempt to get a non-blocking exclusive lock on the file. If that attempt fails it falls back to the second policy rule "BLOCKEX" and tries again to get an exclusive lock on the file, but this time by blocking (waiting for its turn). If that second attempt fails, the File::Util object will fail with a detailed error message and a stack trace.
flock_rules( qw/ BLOCKEX IGNORE / );
The File::Util object will first attempt to get a file non-blocking lock on the file. If that attempt fails it will ignore the error, and go on to open the file anyway and no failures will occur or warings be issued.
isbin( [file name] )
Returns 1 if the named file (or directory) exists. Otherwise a value of undef is returned, indicating that the named file either does not exist or is of another file type.
This works the same as Perl's built-in -B file test operator, (see "-X" in perlfunc), it's just easier for some people to remember.
-B
last_access( [file name] )
Returns the last accessed time for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.)
last_changed( [file name] )
Returns the inode change time for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.)
last_modified( [file name] )
Returns the last modified time for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.)
line_count
line_count( [file name] )
Returns the number of lines in the named file. Fails with an error if the named file does not exist.
list_dir
list_dir( [directory name] , [--opts] )
Returns alphabetically sorted all file names in the directory specified if it exists. Fails with an error message if no such directory is found, or the directory is inaccessible.
The behavior of this method has changed slightly after version 3.29. If running with the --fatals-as-warning flag, the previous behavior was to abort immediately. This is not the case anymore. If running with the --fatals-as-warning flag, list_dir() will still emit a warning when it encounters an otherwise fatal error, but it will also return whatever directory contents it is able to successfully access.
--fatals-as-warning
list_dir()
--dirs-only
return only directory contents which are directories
--files-only
return only directory contents which are files
--no-fsdots
do not include "." and ".." in the list of directory contents
--pattern
return only files/directories matching pattern provided. argument should be plain text string. It will be converted to a perl regex and passed to CORE::grep as the method scans through directory listings for a match.
(ex- '--pattern=\.txt$' returns all file/directory names ending in ".txt". It will match "foo.txt", but not "foo.txt.gz" because of the "$" anchor in the regular expression passed in.)
'--pattern=\.txt$'
or for the opposite effect, '--pattern=.*(?<!\.txt)$' returns all file/directory names that don't end in ".txt"
'--pattern=.*(?<!\.txt)$'
--with-paths
Include file paths with the contents of the directory list, relative to the directory named in the call.
--recurse
Recurse subdirectories
--follow
Recurse subdirectories, same as --recurse
--dirs-as-ref
When returning directory listing, include first a reference to the list of subdirectories found, followed by anything else returned by the call.
--files-as-ref
When returning directory listing, include last a reference to the list of files found, preceded by a list of subdirectories found (or preceded by a list reference to subdirectories found if --dirs-as-ref was also used).
--as-ref
Return a pair list references: the first is a reference to any subdirectories found by the call, the second is a reference to any files found by the call.
--sl-after-dirs
Append a directory separator ("/, "\", or ":" depending on your system) to all directories found by the call. Useful in visual displays for quick differentiation between subdirectories and files.
--ignore-case
Items returned by the call to this method are sorted alphabetically by default, so "Zoo.txt" comes before "alligator.txt" because the alphabetical sort is case-sensitive. This is also the way directories are listed at the system level on most operating systems.
If you'd like the directory contents returned by this method to be sorted without regard to case , use this flag.
--count-only
Returns a single value: an integer reflecting the number of items found in the directory after applying the filter criteria specified by any other flags (ie- "--dirs-only", "--recurse", etc.) that may have been passed in as well.
load_dir
load_dir( [directory name] , [--ds-type] )
Returns a data structure containing the contents of each file present in the named directory.
The type of data structure returned is determined by the optional data-type switch. Only one option may be used for a given call to this method. Recognized options are listed below.
load_dir()
--as-list
Causes the method to return a list comprised of the contents loaded from each file (in case-sensitive order) located in the named directory.
--as-listref
Same as above, except an array reference to the list of items is returned rather than the list itself.
--as-hashref
Implicit. If no option is passed in, the default behavior is to return a reference to an anonymous hash whose keys are the names of each file in the specified directory; the hash values for contain the contents of the file represented by its corresponding key.
Note: This method does not distinguish between plain files and other file types such as binaries, FIFOs, sockets, etc.
Restrictions imposed by the current "read limit" (see the readlimit()) entry below will be applied to the files opened by this method as well. Adjust the readlimit as necessary.
my $files = $fu->load_dir('directory/to/load/');
The above code creates an anonymous hash reference that is stored in the variable named "$files". The keys and values of the hash referenced by "$files" would resemble those of the following code snippet (given that the files in the named directory were the files 'a.txt', 'b.html', 'c.dat', and 'd.conf')
$files
my($files) = { 'a.txt' => "the contents of file a.txt", 'b.html' => "the contents of file b.html", 'c.dat' => "the contents of file c.dat", 'd.conf' => "the contents of file d.conf", };
load_file
load_file( [file name] , [--opts] )
load_file( 'FH' => [file handle reference] , [--opts] )
If [file name] is passed, returns the contents of [file name] in a string. If a [file handle reference] is passed instead, the filehandle will be CORE::read() and the data obtained by the read will be returned in a string.
CORE::read()
If you desire the contents of the file (or file handle data) in a list of lines instead of a single string, this can be accomplished through the use of the --as-lines flag (see below).
--as-lines
load_file()
If this flag is passed then your call to load_file will return an ordered list of strings, each of which is a line from the file [file name]. The lines are returned in the order they are read, from the beginning of the file to the end.
This is not the default behavior. The default behavior is for load_file to return a single string containing the entire contents of the file, including line break characters.
--no-lock
By default this method will attempt to get a lock on the file while it is being read, following whatever rules are in place for the flock policy established either by default (implicitly) or changed by you in a call to File::Util::flock_rules() (see the flock_rules()) entry below.
This method will not try to get a lock on the file if the File::Util object was created with the option --no-lock or if the method was called with the option --no-lock.
This method will automatically call binmode() on binary files for you. If you pass in a filehandle instead of a file name you do not get this automatic check performed for you. In such a case, you'll have to call binmode() on the filehandle yourself. Once you pass a filehandle to this method it has no way of telling if the file opened to that filehandle is binary or not.
Notes: This method does not distinguish between plain files and other file types such as binaries, FIFOs, sockets, etc.
make_dir
make_dir( [new directory name] , [bitmask], [--opts] )
Attempts to create (recursively) a directory as [new directory name] with the [bitmask] provided. The bitmask is an optional argument and defaults to 0777. If specified, the bitmask must be supplied in the form required by the native perl umask function. see "umask" in perlfunc for more information about the format of the bitmask argument.
As mentioned above, the recursive creation of directories is transparently handled for you. This means that if the name of the directory you pass in contains a parent directory that does not exist, the parent directory(ies) will be created for you automatically and silently in order to create the final directory in the [new directory name].
Simply put, if [new directory] is "/path/to/directory" and the directory "/path/to" does not exist, the directory "/path/to" will be created and the "/path/to/directory" directory will be created thereafter. All directories created will be created with the [bitmask] you specify, or with the default of 0777.
Upon successful creation of the [new directory name], the [new directory name] is returned to the caller.
make_dir()
--if-not-exists
If this flag is passed in then make_dir will not attempt to create the directory if it already exists. Rather it will return the name of the directory as it normally would if the directory did not exist previous to calling this method.
If a call to this method is made without the --if-not-exists flag and the directory specified as [new directory name] does in fact exist, an error will result as it is impossible to create a directory that already exists.
max_dives
max_dives( [integer] )
When called without any arguments, this method returns an integer reflecting the current number of times the File::Util object will dive into the subdirectories it discovers when recursively listing directory contents from a call to File::Util::list_dir(). The default is 1000. If the number is exceeded, the File::Util object will fail with a diagnostic error message.
File::Util::list_dir()
When called with an argument, it sets the maximum number of times a File::Util object will recurse into subdirectories before failing with an error message.
This method can only be called with a numeric integer value. Passing a bad argument to this method will cause it to fail with an error message.
(see list_dir)
Returns 1 if the machine on which the code is running requires that binmode() (a built-in function) be called on open file handles, or returns 0 if not. (see "binmode" in perlfunc.) This is a constant method. It accepts no arguments and will always return the same value for the system on which it is executed.
binmode()
new
new( ['parameters' => 'values', etc], [--flags] )
This is the File::Util constructor method. eg- It returns a new File::Util object reference when you call it. It recognizes various parameters and flags that govern the behavior of the new File::Util object.
new()
Optionally specify this option to the File::Util::new method instruct the new object that it should never attempt to use flock() in it's I/O operations. The default is to use flock() when available on your system. Specify this option with a true or false value, true to use flock(), false to not use it.
File::Util::new
Optionally specify this option to the File::Util::new method to instruct the new object that it should never attempt to open and read in a file greater than the number of bytes you specify. Obviously this argument can only be a numeric integer value, otherwise it will be silently ignored. The default readlimit for File::Util objects is 52428800 bytes (50 megabytes).
Optionally specify this option to the File::Util::new method to instruct the new object to set the maximum number of times it will recurse into subdirectories while performing directory listing operations before failing with an error message. This argument can only be a numeric integer value, otherwise it will be silently ignored.
Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return undef instead of the value(s) that would normally be returned by the call, and to send an error message to STDERR as well.
--fatals-as-status
Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return undef instead of the value(s) that would normally be returned by the call.
--fatals-as-errmsg
Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return an error message instead of the value(s) that would normally be returned by the call.
open_handle
open_handle( file => [file name], [--opts] )
open_handle( file => [file name], mode => [mode], [--opts] )
open_handle( file => [file name], mode => [mode], bitmask => [bitmask], [--opts] )
open_handle( file => [file name], mode => [mode], bitmask => [bitmask], dbitmask => [bitmask], [--opts] )
Attempts to get a unique open file handle on [file name] in [mode] mode. Returns the file handle if successful or generates a fatal error with a diagnostic message if the operation fails.
You will need to remember to call close() on the filehandle yourself, at your own discretion. Leaving filehandles open is not a good practice, and is not recommended. see "close" in perlfunc).
close()
Once you have the file handle you would use it as you would use any file handle. Remember that unless you specifically turn file locking off when the File::Util object is created (see (see new) or by using the --no-lock flag when calling open_handle, that file locking is going to automagically be handled for you behind the scenes, so long as your OS supports file locking of any kind at all. Great! It's very convenient for you to not have to worry about portably taking care of file locking between one application and the next; by using File::Util in all of them, you know that you're covered.
File::Util
A slight inconvenience for the price of a larger set of features (compare write_file to this method) you will have to release the file lock on the open handle yourself. File::Util can't manage it for you anymore once it hands the handle over to you. At that point, it's all yours. In order to release the file lock on your file handle, call unlock_open_handle() on it. Otherwise the lock will remain for the life of your process. If you don't want to use the free portable file locking, remember the --no-lock flag, which will turn off file locking for your open handle. Seldom, however, should you ever opt to not use file locking unless you really know what you are doing.
If the file does not yet exist it will be created, and it will be created with a bitmask of [bitmask] if you specify a file creation bitmask using the 'bitmask' option, otherwise the file will be created with the default bitmask of 0777.
'bitmask'
If specified, the bitmask must be supplied in the form required by the native perl umask function. see "umask" in perlfunc for more information about the format of the bitmask argument. If the file [file name] already exists then the bitmask argument has no effect and is silently ignored.
Any non-existent directories in the path preceding the actual file name will be automatically (and silently - no warnings) created for you and any new directories will be created with a bitmask of [dbitmask], provided you specify a directory creation bitmask with the 'dbitmask' option.
'dbitmask'
If specified, the directory creation bitmask [dbitmask] must be supplied in the form required by the native perl umask function.
If there is an error while trying to create any preceding directories, the failure results in a fatal error with a diagnostic error message. If all directories preceding the name of the file already exist, the dbitmask argument has no effect and is silently ignored.
The default behavior of open_handle() is to open file handles using Perl's native open() (see "open" in perlfunc). Unless you use the --use-sysopen flag, the following modes and only these modes are valid.
open_handle()
open()
--use-sysopen
'mode' => 'read'
[file name] is opened in read-only mode. If the file does not yet exist then a fatal error will occur with a diagnostic help message to help you troubleshoot the problem.
'mode' => 'write'
[file name] is created if it does not yet exist. If [file name] already exists then its contents are overwritten with the new content provided.
'mode' => 'append'
[file name] is created if it does not yet exist. If [file name] already exists its contents will be preserved and the new content you provide will be appended to the end of the file.
Optionally you can ask File::Util to open your handle using CORE::sysopen instead of using the native Perl CORE::open(). This is accomplished by passing in the --use-sysopen flag. Using this feature opens up more possibilities as far as the open modes you can choose from, but also carries with it a few caveats so you have to be careful, just as you'd have to be a little more careful when using sysopen() anyway.
CORE::sysopen
CORE::open()
sysopen()
Specifically you need to remember that when using this feature you must NOT mix different types of I/O when working with the file handle. You can't go opening file handles with sysopen() and print to them as you normally would print to a file handle. You have to use syswrite() instead. The same applies here. If you get a sysopen()'d filehandle from open_handle() it is imperative that you use syswrite() on it. You'll also need to use sysseek() and other type of sys* commands on the filehandle instead of their native Perl equivalents.
syswrite()
sysseek()
sys
(see "sysopen" in perlfunc, "syswrite" in perlfunc, "sysseek" in perlfunc, "sysread" in perlfunc)
That said, here are the different modes you can choose from to get a file handle when using the --use-sysopen flag. Remember that these won't work unless you use the flag, and will generate an error if you try using them without it. The standard 'read', 'write', and 'append' modes are already available to you by default. These are the extended modes:
'read'
'write'
'append'
'mode' => 'rwcreate'
[file name] is opened in read-write mode, and will be created for you if it does not already exist.
'mode' => 'rwupdate'
[file name] is opened for you in read-write mode, but must already exist. If it does not exist, a fatal error will result and a diagnostic help message will be printed out to help you troubleshoot the problem.
'mode' => 'rwclobber'
[file name] is opened for you in read-write mode. If the file already exists it's contents will be "clobbered" or wiped out. The file will then be empty and you will be working with the then-truncated file. This can not be undone. Once you call open_handle() using this option, your file WILL be wiped out. If the file does not exist yet, it will be created for you.
'mode' => 'rwappend'
[file name] will be opened for you in read-write mode ready for appending. The file's contents will not be wiped out; they will be preserved and you will be working in append fashion. You will only be able to write starting at the end of the file. If the file does not exist, it will be created for you.
Remember to use sysread() and not plain read() when reading those sysopen()'d filehandles!
sysread()
read()
--binmode
Makes sure that CORE::binmode() is called on the filehandle when your content is written. This is useful for times when the content you are writing to file is a binary stream. (see "binmode" in perlfunc).
This method will not try to get a lock on the file if the File::Util object was created with the option --no-lock or if this method is called with the option --no-lock.
Instead of opening the file using Perl's native open() command, File::Util will open the file with the sysopen() command. You will have to remember that your filehandle is a sysopen()'d one, and that you will not be able to use native Perl I/O functions on it. You will have to use the sys* equivalents. See perlopentut for a more in-depth explanation of why you can't mix native Perl I/O with system I/O.
readlimit
readlimit( [integer] )
By default, the largest size file that File::Util will read into memory and return via the load_file is 52428800 byptes (50 megabytes).
This value can be modified by calling this method with an integer value reflecting the new limit you want to impose, in bytes. For example, if you want to set the limit to 10 megabytes, call the method with an argument of 10485760.
If this method is called without an argument, the read limit currently in force for the File::Util object will be returned.
return_path( [string] )
Takes the file path from the file name provided and returns it such that "/foo/bar/baz.txt" is returned "/foo/bar".
size( [file name] )
Returns the file size of [file name] in bytes. Returns 0 if the file is empty, returns undef if the file does not exist.
0
strip_path( [string] )
Strips the file path from the file name provided and returns the file name only.
touch
touch( [file name] )
Behaves like the *nix touch command; Updates the access and modification times of the specified file to the current time. If the file does not exist, File::Util tries to create it empty. This method will fail with a fatal error if system permissions deny alterations to or creation of the file.
Returns 1 if successful. If unsuccessful, fails with a descriptive error message about what went wrong.
1
trunc
trunc( [file name] )
Truncates [file name] (i.e.- wipes out, or "clobbers" the contents of the specified file. Returns 1 if successful. If unsuccessful, fails with a descriptive error message about what went wrong.
unlock_open_handle
unlock_open_handle([file handle])
Release the flock on a file handle you opened with open_handle.
Returns true on success, false on failure. Will not raise a fatal error if the unlock operation fails. You can capture the return value from your call to this method and die() if you so desire. Failure is not ever very likely, or File::Util wouldn't have been able to get a portable lock on the file in the first place.
die()
If File::Util wasn't able to ever lock the file due to limitations of your operating system, a call to this method will return a true value.
If file locking has been disabled on the file handle via the --no-lock flag at the time open_handle was called, or if file locking was disabled using the use_flock method, or if file locking was disabled on the entire File::Util object at the time of its creation (see new()), calling this method will have no effect and a true value will be returned.
use_flock
use_flock( [true / false value] )
When called without any arguments, this method returns a true or false value to reflect the current use of flock() within the File::Util object.
When called with a true or false value as its single argument, this method will tell the File::Util object whether or not it should attempt to use flock() in its I/O operations. A true value indicates that the File::Util object will use flock() if available, a false value indicates that it will not. The default is to use flock() when available on your system.
write_file
write_file( file' => [file name], 'content' => [string], [--opts] )
write_file( file => [file name], content => [string], mode => [mode], [--opts] )
write_file( file => [file name], content => [string], mode => [mode], bitmask => [bitmask], [--opts] )
write_file( file => [file name], content => [string], mode => [mode], bitmask => [bitmask], dbitmask => [bitmask], [--opts] )
Attempts to write [string] to [file name] in mode [mode]. If the file does not yet exist it will be created, and it will be created with a bitmask of [bitmask] if you specify a file creation bitmask using the 'bitmask' option, otherwise the file will be created with the default bitmask of 0777.
[string] should be a string or a scalar variable containing a string. The string can be any type of data, such as a binary stream, or ascii text with line breaks, etc. Be sure to pass in the --binmode flag for binary streams.
Returns 1 if successful or fails (fatal) with an error message if not successful.
write_file()
Makes sure that CORE::binmode() is called on the filehandle when your content is written. This is useful for times when the content you are writing to file is a binary stream.
--empty-writes-OK
Allows you to call this method without providing a content argument (it lets you create an empty file without warning you or failing. Be advised that if you use this flag, it will have the same effect as truncating a file that already has content in it (i.e.- it will "clobber" non-empty files)
valid_filename( [string] )
For the given string, returns 1 if the string is a legal file name for the system on which the program is running, or returns undef if it is not. This method does not test for the validity of file paths! It tests for the validity of file names only. (It is used internally to check beforehand if a file name is useable when creating new files, but is also a public method available for external use.)
Returns the correct new line character (or character sequence) for the system on which your program runs.
Returns the correct directory path separator for the system on which your program runs.
OS
Returns the File::Util keyword for the operating system FAMILY it detected. The keyword for the detected operating system will be one of the following, derived from the conents of $^O, or if $^O can not be found, from the contents of $Config::Config{osname} (see native Config library), or if that doesn't contain a recognizable value, finally falls back to UNIX.
$^O
$Config::Config{osname}
UNIX
Generally speaking, Linux operating systems are going to be detected as UNIX. This isn't a bug. The OS FAMILY to which it belongs uses UNIX style filesystem conventions and line endings, which are the relevant things to file handling operations.
Specifics: OS name =~ /^(?:darwin|bsdos)/i
Specifics: OS name =~ /^cygwin/i
Specifics: OS name =~ /^MSWin/i
Specifics: OS name =~ /^vms/i
Specifics: OS name =~ /^dos/i
Specifics: OS name =~ /^MacOS/i
Specifics: OS name =~ /^epoc/i
Specifics: OS name =~ /^os2/i
use File::Util; my $f = File::Util->new(); # option --no-fsdots excludes "." and ".." from the list my @dirs_and_files = $f->list_dir('/foo', '--no-fsdots');
use File::Util; my $f = File::Util->new(); my @dirs_and_files = $f->list_dir('/foo', '--recurse');
use File::Util; my $f = File::Util->new(); my @dirs_and_files = $f->list_dir('/foo', '--files-only');
use File::Util; my $f = File::Util->new(); my @dirs_and_files = $f->list_dir('/foo', '--dirs-only');
use File::Util; my $f = File::Util->new(); my @dirs_and_files = $f->list_dir('/foo', qw/--no-fsdots --count-only/);
use File::Util; my $f = File::Util->new(); my( $dirs, $files ) = $f->list_dir('/foo', '--as-ref'); -OR- my( $dirs, $files ) = $f->list_dir('.', qw/--dirs-as-ref --files-as-ref/);
use File::Util; my $f = File::Util->new(); my $contents = $f->load_file('filename');
use File::Util; my $f = File::Util->new(); my @contents = $f->load_file('filename','--as-lines');
use File::Util; my $f = File::Util->new(); my $fh = $f->open_handle( file => 'new_filename', mode => 'read' );
use File::Util; my $f = File::Util->new(); my $fh = $f->open_handle( file => 'new_filename', mode => 'write' );
use File::Util; my $content = 'Pathelogically Eclectic Rubbish Lister'; my $f = File::Util->new(); $f->write_file( file => 'a new file.txt', content => $content ); # optionally specify a creation bitmask when writing to a new file $f->write_file( file => 'a new file.txt', bitmask => oct 777, content => $content );
use File::Util; my $content = 'Pathelogically Eclectic Rubbish Lister'; my $f = File::Util->new(); $f->write_file( file => 'a new file.txt', mode => 'append', content => $content );
use File::Util qw( valid_filename ); if (valid_filename("foo?+/bar~@/#baz.txt")) { print "file name is valid" else { print "file name contains illegal characters" } -OR- use File::Util; print File::Util->valid_filename("foo?+/bar~@/#baz.txt") ? 'ok' : 'bad'; -OR- use File::Util; my $f = File::Util->new(); print $f->valid_filename("foo?+/bar~@/#baz.txt") ? 'ok' : 'bad';
use File::Util; my $f = File::Util->new(); my $linecount = $f->line_count('foo.txt');
use File::Util; my $f = File::Util->new(); # 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');
use File::Util; my $f = File::Util->new(); # 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 Mac # (prints "foo:bar") print $f->return_path('foo:bar:baz');
use File::Util qw( can_flock ); print can_flock; -OR- print File::Util->can_flock; -OR- my $f = File::Util->new(); print $f->can_flock;
use File::Util qw( needs_binmode ); print needs_binmode; -OR- use File::Util; print File::Util->needs_binmode; -OR- use File::Util; my $f = File::Util->new(); print $f->needs_binmode;
use File::Util; my $f = File::Util->new(); my $is_readable = $f->can_read('foo.txt');
use File::Util; my $f = File::Util->new(); my $is_writable = $f->can_write('foo.txt');
use File::Util; my $f = File::Util->new(); # 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' ); # prints "_foo_!_@so~me#illegal$_file&(name" # (yes, that is a legal filename) print $f->escape_filename(q[\foo*!_@so~me#illegal$*file&(name]);
use File::Util qw( ebcdic ); print ebcdic; -OR- use File::Util; print File::Util->ebcdic; -OR- use File::Util; my $f = File::Util->new(); print $f->ebcdic;
use File::Util qw( file_type ); print file_type('foo.exe'); -OR- use File::Util; print File::Util->file_type('bar.txt'); -OR- use File::Util; my $f = File::Util->new(); print $f->file_type('/dev/null');
use File::Util qw( bitmask ); print bitmask('/usr/sbin/sendmail'); -OR- use File::Util; print File::Util->bitmask('C:\COMMAND.COM'); -OR- use File::Util; my $f = File::Util->new(); print $f->bitmask('/dev/null');
use File::Util qw( created ); print scalar localtime created('/usr/bin/exim'); -OR- use File::Util; print scalar localtime File::Util->created('C:\COMMAND.COM'); -OR- use File::Util; my $f = File::Util->new(); print scalar localtime $f->created('/bin/less');
use File::Util qw( last_access ); print scalar localtime last_access('/usr/bin/exim'); -OR- use File::Util; print scalar localtime File::Util->last_access('C:\COMMAND.COM'); -OR- use File::Util; my $f = File::Util->new(); print scalar localtime $f->last_access('/bin/less');
use File::Util qw( last_changed ); print scalar localtime last_changed('/usr/bin/vim'); -OR- use File::Util; print scalar localtime File::Util->last_changed('C:\COMMAND.COM'); -OR- use File::Util; my $f = File::Util->new(); print scalar localtime $f->last_changed('/bin/cpio');
use File::Util qw( last_modified ); print scalar localtime last_modified('/usr/bin/exim'); -OR- use File::Util; print scalar localtime File::Util->last_modified('C:\COMMAND.COM'); -OR- use File::Util; my $f = File::Util->new(); print scalar localtime $f->last_modified('/bin/less');
use File::Util; my $f = File::Util->new(); $f->make_dir('/var/tmp/tempfiles/foo/bar/'); # optionally specify a creation bitmask to be used in directory creations $f->make_dir('/var/tmp/tempfiles/foo/bar/',0755);
use File::Util qw( touch ); touch('somefile.txt'); -OR- use File::Util; my $f = File::Util->new(); $f->touch('/foo/bar/baz.tmp');
use File::Util; my $f = File::Util->new(); $f->trunc('/wibble/wombat/noot.tmp');
use File::Util qw( SL ); print SL; -OR- use File::Util; print File::Util->SL; -OR- use File::Util; my $f = File::Util->new(); print $f->SL;
use File::Util qw( NL ); print NL; -OR- use File::Util; print File::Util->NL; -OR- use File::Util; my $f = File::Util->new(); print $f->NL;
# Code changes the file suffix of all files in a directory ending in # *.foo so that they afterward end in *.bar use strict; use vars qw( $dir ); use File::Util qw( NL SL ); my $f = File::Util->new(); my $dir = '../wibble'; my $old = 'foo'; my $new = 'bar'; my @files = $f->list_dir($dir, '--files-only'); foreach ( @files ) { # don't change the file suffix unless it is *.foo if ($_ =~ /\.$old$/o) { my $newname = $_; $newname =~ s/\.$old/\.$new/; if (rename($dir . SL . $_, $dir . SL . $newname)) { print qq($_ -> $newname), NL } else { warn <<__ERR__ } Couldn't rename "$_" to "$newname"! __ERR__ } else { print <<__NOCHANGE__ } File retained as "$_" __NOCHANGE__ }
# This code removes a directory and everything in it use strict; # always use File::Util qw( NL ); my $f = File::Util->new(); my $removedir = '/path/to/directory/youwanttodelete'; my @gonners = $f->list_dir($removedir, '--follow'); # remove directory and everything in it my( $a, $b ); @gonners = reverse sort { length $a <=> length $b } @gonners; foreach ( @gonners, $removedir ) { print "Removing $_ ..." . NL; -d $_ ? rmdir($_) || die $! : unlink($_) || die $!; } print 'Done. w00T!', NL x 2;
# This code opens a file, wraps its lines, and saves the file with # the newly formatted content use strict; # always use File::Util qw( NL ); use Text::Wrap qw( wrap ); $Text::Wrap::columns = 72; # wrap text at this many columns my $f = File::Util->new(); my $textfile = 'myreport.txt'; # file to wrap and save $f->write_file( filename => $textfile, content => wrap('', '', $f->load_file($textfile)) ); print 'Done.', NL x 2;
# This code opens a file, reads a number value, increments it, # then saves the newly incremented value back to the file use strict; # always use File::Util; my $f = File::Util->new(); my $counterfile = 'counter.txt'; # if the counter file doesn't exist, let's make one if ( !$f->existent( $counterfile ) ) { $f->touch($counterfile); } my $count = $f->load_file( $counterfile ); # convert textual number to in-memory int type, -this will default # to a zero if it encounters non-numerical or empty content chomp $count; # strip off any trailing lines $count =~ s/[^[:digit:]]//g; # remove non-numeric data $count = 0 if "$count" eq ''; # set count to 0 if empty string $count = int $count; # numberify $count print 'Count value from file: ' . $f->load_file($counterfile), $f->NL; $count++; # increment the counter value by 1 # save the incremented count back to the counter file $f->write_file( filename => $counterfile, content => $count); # verify that "it worked" print 'Count is now: ' . $f->load_file($counterfile), $f->NL; print 'Done.', $f->NL x 2;
# Code does a batch find or search and replace for all files in a given # directory, recursively or non-recursively based on choices set forth # in the code. use strict; use File::Util qw( NL SL ); # will get search pattern from file named below use constant SFILE => './sr/searchfor'; # will get replace pattern from file named below use constant RFILE => './sr/replacewith'; # will perform batch operation in directory named below use constant INDIR => '/foo/bar/baz'; # specify whether the operation will do a find or a search and replace use constant RMODE => [qw| read-only write |]->[1]; # set the options for the search (will or will not recurse, etc) my @opts = [qw/ --files-only --with-paths --recurse /]->[0,1]; # create new File::Util object, set File::Util to send a warning for # fatal errors instead of dieing my $f = File::Util->new('--fatals-as-warning'); my $rstr = $f->load_file(RFILE); my $spat = quotemeta $f->load_file(SFILE); $spat = qr/$spat/; my $gsbt = 0; my $action = RMODE eq 'read-only' ? 'detections' : 'substitutions'; my @files = $f->list_dir(INDIR, @opts); for (my $i = 0; $i < @files; ++$i) { next if $f->isbin( $files[$i] ); my $sbt = 0; my $file = $f->load_file( $files[$i] ); $file =~ s/$spat/++$sbt;++$gsbt;$rstr/ge; $f->write_file( file => $files[$i], content => $file) if RMODE eq 'write'; print $sbt ? qq($sbt $action in $files[$i]) . NL : ''; } print( NL . <<__DONE__ . NL x 2 ) and exit; $gsbt $action in ${\scalar(@files)} files. __DONE__
use strict; use vars qw( $a $b ); use File::Util qw( NL ); my $ind = ''; my $f = File::Util->new(); my @o = qw( --with-paths --sl-after-dirs --no-fsdots --files-as-ref --dirs-as-ref ); my $filetree = {}; my $treetrunk = '/var/'; my( $subdirs, $sfiles ) = $f->list_dir($treetrunk, @o); $filetree = [{ $treetrunk => [ sort({ uc $a cmp uc $b } @$subdirs, @$sfiles) ] }]; descend( $filetree->[0]{ $treetrunk }, scalar(@$subdirs) ); walk( @$filetree ); sub descend { my( $parent, $dirnum ) = @_; for (my $i = 0; $i < $dirnum; ++$i) { my $current = $parent->[$i]; next unless -d $current; my( $subdirs, $sfiles ) = $f->list_dir($current, @o); map { $_ = $f->strip_path($_) } @$sfiles; splice(@$parent,$i,1,{ $current => [ sort({ uc $a cmp uc $b } @$subdirs, @$sfiles) ] }); descend( $parent->[$i]{ $current }, scalar @$subdirs ); } return $parent; } sub walk { my $dir = shift(@_); foreach (@{ [ %$dir ]->[1] }) { my $mem = $_; if (ref $mem eq 'HASH') { print $ind . $f->strip_path([ %$mem ]->[0]) . '/', NL; $ind .= ' ' x 3; walk( $mem ); $ind = substr( $ind, 3 ); } else { print $ind . $mem, NL } } }
Send bug reports and patches to the CPAN Bug Tracker for File::Util at https://rt.cpan.org/Dist/Display.html?Name=File%3A%3AUtil
If you want to get help, contact the authors (links below in the AUTHORS section)
I fully endorse http://www.perlmonks.org as an excellent source of help with Perl in general.
The project website for File::Util is at https://github.com/tommybutler/file-util/wiki
The git repository for File::Util is on Github at https://github.com/tommybutler/file-util
Clone it at git://github.com/tommybutler/file-util.git
This project was a private endeavor for too long so don't hesitate to pitch in. I want to say I very much appreciate the emails, bug reports, patches, and all those who contribute their time and talents as CPAN testers.
Tommy Butler http://www.atrixnet.com/contact
Copyright(C) 2001-2013, Tommy Butler. All rights reserved.
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.
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.
File::Slurp, Path::Class, Exception::Handler
To install File::Util, copy and paste the appropriate command in to your terminal.
cpanm
cpanm File::Util
CPAN shell
perl -MCPAN -e shell install File::Util
For more information on module installation, please visit the detailed CPAN module installation guide.