NAME¶
File::Util - Easy, versatile, portable file handling
DESCRIPTION¶
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.
SYNOPSIS¶
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
INSTALLATION¶
To install this module type the following at the command prompt:
perl Makefile.PL
make
make test
make install
On windows machines use nmake rather than make; those running cygwin don't have
to worry about this. If you don't know what cygwin is, use nmake and check out
http://cygwin.com/ after you're done installing this module if you want to
find out.
ISA¶
- Exporter
- Class::OOorNO
EXPORTED SYMBOLS¶
Exports nothing by default.
EXPORT_OK¶
The following symbols comprise @File::Util::EXPORT_OK), and as such are
available for import to your namespace only upon request.
"bitmask"
(see bitmask)
"can_flock"
(see can_flock)
"can_read"
(see can_read)
"can_write"
(see can_write)
"created"
(see created)
"ebcdic"
(see ebcdic)
"escape_filename"
(see escape_filename)
"existent"
(see existent)
"file_type"
(see file_type)
"isbin"
(see isbin)
"last_access"
(see last_access)
"last_changed"
(see last_changed)
"last_modified"
(see last_modified)
"NL"
(see NL)
"needs_binmode"
(see needs_binmode)
"return_path"
(see return_path)
"size"
(see size)
"SL"
(see SL)
"strip_path"
(see strip_path)
"valid_filename"
(see valid_filename)
Note: Symbols in @Class::OOorNO::EXPORT_OK are also available for import.
:all (exports all of @File::Util::EXPORT_OK)
METHODS¶
Note: Some of the methods listed will state that they are autoloaded
methods. Autloaded methods are not compiled at runtime as part of your process
and only get created if called somewhere in your program.
(see
AutoLoader.)
Methods listed in alphabetical order.
"bitmask"¶
- Syntax: "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. This is an autoloaded method.
"can_flock"¶
- Syntax: "can_flock"
- 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 an autoloaded
method. This is a constant subroutine. It accepts no arguments and will
always return the same value for the system on which it is executed.
Note: Perl will try to support or emulate flock whenever it can via
available system calls, namely "flock"; "lockf"; or
with "fcntl".
"can_read"¶
- Syntax: "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. This is an autoloaded method.
"can_write"¶
- Syntax: "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. This is an autoloaded method.
"created"¶
- Syntax: "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.) This is
an autoloaded method.
"ebcdic"¶
- Syntax: "ebcdic"
- Returns 1 if the machine on which the code is running uses
EBCDIC, or returns 0 if not. (see perlebcdic.) This is an
autoloaded method. This is a constant subroutine. It accepts no arguments
and will always return the same value for the system on which it is
executed.
"escape_filename"¶
- Syntax: "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. This is an autoloaded method.
"existent"¶
- Syntax: "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. This is an autoloaded method.
"file_type"¶
- Syntax: "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.) This is an
autoloaded method.
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"¶
- Syntax: "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:
- ex- "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.
- ex- "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.
- ex- "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.
This is an autoloaded method.
"isbin"¶
- Syntax: "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. This is an autoloaded method.
"last_access"¶
- Syntax: "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.) This is
an autoloaded method.
"last_changed"¶
- Syntax: "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.) This is
an autoloaded method.
"last_modified"¶
- Syntax: "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.) This is
an autoloaded method.
"line_count"¶
- Syntax: "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"¶
- Syntax: "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.
- Flags accepted by
"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.)
or for the opposite effect, '--pattern=.*(?<!\.txt)$' returns all
file/directory names that don't end in ".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
preceeded 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 seperator ("/, "\", 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"¶
- Syntax: "load_dir( [directory name] ,
[--ds-type] )"
- Returns a data structure containing the contents of each
file present in the named directory. This is an autoloaded method.
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.
- Flags accepted by
"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" *(default)
- 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')
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"¶
- Syntax: "load_file( [file name] , [--opts]
)"
- OR: "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.
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).
- Flags accepted by
"load_file()"
- "--as-lines"
- 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.
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.
"make_dir"¶
- Syntax: "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.
- Flags accepted by
"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.
This is an autoloaded method.
"max_dives"¶
- Syntax: "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.
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)
This is an autoloaded method.
"needs_binmode"¶
- Syntax: "needs_binmode"
- 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 an autoloaded method. This is a constant
subroutine. It accepts no arguments and will always return the same value
for the system on which it is executed.
"new"¶
- Syntax: "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.
- Parameters accepted by
"new()"
- use_flock => true/false value
- 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.
- readlimit => positive integer
- 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).
- max_dives => positive integer
- 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.
- Flags accepted by
"new()"
- "--fatals-as-warning"
- 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"¶
- Syntax: "open_handle('file' => [file name],
[--opts])"
- OR: "open_handle('file' => [file name],
'mode' => [mode], [--opts])"
- OR: "open_handle('file' => [file name],
'mode' => [mode], 'bitmask' => [bitmask], [--opts])"
- OR: "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).
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.
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.
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 preceeding 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.
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 preceeding directories, the
failure results in a fatal error with a diagnostic error message. If all
directories preceeding the name of the file already exist, the dbitmask
argument has no effect and is silently ignored.
- Native Perl open modes
- 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.
- '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' (this is the default mode)
- [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.
- System level open modes ("open a la
C")
- 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.
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.
(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:
- '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!
- Flags accepted by
"open_handle()"
- "--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).
- "--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 this method is
called with the option "--no-lock".
- "--use-sysopen"
- 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.
This is an autoloaded method.
"readlimit"¶
- Syntax: "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.
This is an autoloaded method.
"return_path"¶
- Syntax: "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".
This is an autoloaded method.
"size"¶
- Syntax: "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.
This is an autoloaded method.
"strip_path"¶
- Syntax: "strip_path( [string] )"
- Strips the file path from the file name provided and
returns the file name only.
"touch"¶
- Syntax: "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.
This is an autoloaded method.
"trunc"¶
- Syntax: "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.
This is an autoloaded method.
"unlock_open_handle"¶
- Syntax: "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.
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.
This is an autoloaded method, due to open_handle also being autoloaded.
"use_flock"¶
- Syntax: "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.
This is an autoloaded method.
"write_file"¶
- Syntax: "write_file('file' => [file name],
'content' => [string], [--opts])"
- OR: "write_file('file' => [file name],
'content' => [string], 'mode' => [mode], [--opts])"
- OR: "write_file('file' => [file name],
'content' => [string], 'mode' => [mode], 'bitmask' => [bitmask],
[--opts])"
- OR: "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.
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.
Returns 1 if successful or fails (fatal) with an error message if not
successful.
Any non-existent directories in the path preceeding 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.
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 preceeding directories, the
failure results in a fatal error with a diagnostic error message. If all
directories preceeding the name of the file already exist, the dbitmask
argument has no effect and is silently ignored.
- 'mode' => 'write' (this is the default mode)
- [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.
- Flags accepted by
"write_file()"
- "--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.
- "--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)
- "--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 this method is
called with the option "--no-lock".
"valid_filename"¶
- Syntax: "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.)
CONSTANTS¶
"NL"¶
- Syntax: "NL"
- Returns the correct new line character (or character
sequence) for the system on which your program runs.
"SL"¶
- Syntax: "SL"
- Returns the correct directory path seperator for the system
on which your program runs.
"OS"¶
- Syntax: "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".
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.
- UNIX
- Specifics: OS name =~ /^(?:darwin|bsdos)/i
- CYGWIN
- Specifics: OS name =~ /^cygwin/i
- WINDOWS
- Specifics: OS name =~ /^MSWin/i
- VMS
- Specifics: OS name =~ /^vms/i
- DOS
- Specifics: OS name =~ /^dos/i
- MACINTOSH
- Specifics: OS name =~ /^MacOS/i
- EPOC
- Specifics: OS name =~ /^epoc/i
- OS2
- Specifics: OS name =~ /^os2/i
PREREQUISITES¶
- Perl 5.006 or better
- Class::OOorNO v0.01_1 or better
- Exception::Handler v1.00_0 or better
EXAMPLES¶
Get the names of all files and subdirectories in a directory¶
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');
Get the names of all files and subdirectories in a directory,
recursively¶
use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--recurse');
Get the names of all files (no subdirectories) in a
directory¶
use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--files-only');
Get the names of all subdirectories (no files) in a
directory¶
use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--dirs-only');
Get the number of files and subdirectories in a directory¶
use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo', qw/--no-fsdots --count-only/);
Get the names of files and subdirs in a directory as seperate
array refs¶
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/);
Get the contents of a file in a string¶
use File::Util;
my($f) = File::Util->new();
my($contents) = $f->load_file('filename');
Get the contents of a file in an array of lines in the file¶
use File::Util;
my($f) = File::Util->new();
my(@contents) = $f->load_file('filename','--as-lines');
Get an open file handle for reading¶
use File::Util;
my($f) = File::Util->new();
my($FH_REF) = $f->open_handle(
'file' => 'new_filename',
'mode' => 'read'
);
Get an open file handle for writing¶
use File::Util;
my($f) = File::Util->new();
my($FH_REF) = $f->open_handle(
'file' => 'new_filename',
'mode' => 'write'
);
Write to a new or existing file¶
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' => 0777,
'content' => $content
);
Append to a new or existing file¶
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
);
Determine if something is a valid file name¶
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';
Get the number of lines in a file¶
use File::Util;
my($f) = File::Util->new();
my($linecount) = $f->line_count('foo.txt');
Strip the path from a file name¶
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');
Get the path preceeding a file name¶
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');
Find out if the host system can use flock¶
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;
Find out if the host system needs to call binmode on binary
files¶
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;
Find out if a file can be opened for read (based on file
permissions)¶
use File::Util;
my($f) = File::Util->new();
my($is_readable) = $f->can_read('foo.txt');
Find out if a file can be opened for write (based on file
permissions)¶
use File::Util;
my($f) = File::Util->new();
my($is_writable) = $f->can_write('foo.txt');
Escape illegal characters in a potential file name (and its
path)¶
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]);
Find out if the host system uses EBCDIC¶
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;
Get the type(s) of an existent file¶
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');
Get the bitmask of an existent file¶
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');
Get time of creation for a file¶
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');
Get the last access time for a file¶
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');
Get the inode change time for a file¶
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');
Get the last modified time for a file¶
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');
Make a new directory, recursively if neccessary¶
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);
Touch a file¶
use File::Util qw( touch );
touch('somefile.txt');
-OR-
use File::Util;
my($f) = File::Util->new();
$f->touch('/foo/bar/baz.tmp');
Truncate a file¶
use File::Util;
my($f) = File::Util->new();
$f->trunc('/wibble/wombat/noot.tmp');
Get the correct path seperator for the host system¶
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;
Get the correct newline character for the host system¶
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;
EXAMPLES (Full Programs)¶
Batch File Rename¶
# 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__
}
Recursively remove a directory and all its contents¶
# 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);
foreach (reverse(sort({ length($a) <=> length($b) } @gonners)), $removedir) {
print "Removing $_ ..." . NL;
-d $_ ? rmdir($_) || die $! : unlink($_) || die $!;
}
print 'Done. w00T!', NL x 2;
Wrap the lines in a file at 72 columns, then save it¶
# 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;
Read and increment a counter file, then save it¶
# 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;
Batch Search & Replace¶
# 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__
Pretty-Print A Directory Recursively¶
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));
}
$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) }
}
}
BUGS¶
Send bug reports to the AUTHOR. There are no known bugs at this time.
TODO¶
Add full support for PerlIO layers in "File::Util::open_handle()" and
possibly "File::Util::write_file()".
AUTHOR¶
Tommy Butler <<cpan@atrixnet.com>>
COPYRIGHT¶
Copyright(C) 2001-2007, Tommy Butler. All rights reserved.
LICENSE¶
This library is free software, you may redistribute and/or modify it under the
same terms as Perl itself.
SEE ALSO¶
File::Slurp, Exception::Handler, Class::OOorNO