File::Util::Manual(3pm) | User Contributed Perl Documentation | File::Util::Manual(3pm) |
File::Util::Manual - File::Util Reference
version 4.201720
This manual is is the complete reference to all available public methods for use in File::Util. It also touches on a few other topics as set forth below.
For a "nutshell"-type reference full of actual small example code snippets, take a look at the File::Util::Manual::Examples
For examples of full Programs using File::Util, take a look at the File::Util::Cookbook.
Now we'll start out with some brief notes about what File::Util is (and isn't), then we'll talk about the syntax used in File::Util. After that we discuss custom error handling and diagnostics in File::Util. Finally, the rest of this document will cover File::Util's object methods, one by one, with brief usage examples.
File::Util is a "Pure Perl" library that provides you with several easy-to-use tools to wrangle files and directories. It has higher order methods (that's fancy talk for saying that you can feed subroutine references to some of File::Util's object methods and they will be treated like "callbacks").
File::Util is mainly Object-Oriented Perl, but strives to be gentle and accommodating to those who do not know about or who do not like "OO" interfaces. As such, many of the object methods available in File::Util can also be imported into your namespace and used like regular subroutines to make short work of simple tasks.
For more advanced tasks and features, you will need to use File::Util's object-oriented interface. Don't worry, it's easy, and there are plenty of examples here in the documentation to get you off to a great and productive start. If you run into trouble, help is available.
File::Util tries its best to adhere to these guiding principles:
File::Util makes the right decisions for you with regard to all the little details involved in the vast majority of file-related tasks. File locking is automatically performed for you! File handles are always lexically scoped. Safe reads and writes are performed with hard limits on the amount of RAM you are allowed to consume in your process per file read. (You can adjust the limits.)
In the last several years, there has never been a release of File::Util that intentionally broke code running a previous version. We are unaware of that even happening. File::Util is written to support both old and new features, syntaxes, and interfaces with full backward-compatibility.
These error messages can easily be turned on and off. See DIAGNOSTICS for the details.
File::Util offers significant performance increases over other modules for most directory-walking and searching, whether doing so in a single directory or in many directories recursively. (See also the benchmarking and profiling scripts included in the performance subdirectory as part of this distribution)*
However File::Util is NOT a single-purpose file-finding/searching utility like File::Find::Rule which offers a handful of extra built-in search features that File::Util does not give you out of the box, such as searching for files by owner/group or size. It is possible to accomplish the same things by taking advantage of File::Util's callbacks if you want to, but this isn't the "one thing" File::Util was built to do.
*Sometimes it doesn't matter how fast you can search through a directory 1000 times. Performance alone isn't the best criteria for choosing a module.
In the past, File::Util relied on an older method invocation syntax that was not robust enough to support the newer features that have been added since version 4.0. In addition to making new features possible, the new syntax is more in keeping with what the Perl community has come to expect from its favorite modules, like Moose and DBIx::Class.
# this legacy syntax looks clunky and kind of smells like shell script $f->list_dir( '/some/dir', '--recurse', '--as-ref', '--pattern=[^\d]' );
# This syntax is much more robust, and supports new features $f->list_dir( '/some/dir' => { files_match => { or => [ qr/bender$/, qr/^flexo/ ] }, parent_matches => { and => [ qr/^Planet/, qr/Express$/ ] }, callback => \&deliver_interstellar_shipment, files_only => 1, recurse => 1, as_ref => 1, } )
If you already have code that uses the old syntax, DON'T WORRY -- it's still fully supported behind the scenes. However, for new code that takes advantage of new features like higher order functions (callbacks), or advanced matching for directory listings, you'll need to use the syntax as set forth in this document. The old syntax isn't covered here, because you shouldn't use it anymore.
An Explanation Of The "Options Hashref"
As shown in the code example above, the new syntax uses hash references to specify options for calls to File::Util methods. This documentation refers to these as the "options hashref". The code examples below illustrates what they are and how they are used. Advanced Perl programmers will recognize these right away.
NOTE: "hashref" is short for "hash reference". Hash references use curly brackets and look like this:
my $hashref = { name => 'Larry', language => 'Perl', pet => 'Velociraptor' };
File::Util uses these hash references as argument modifiers that allow you to enable or disable certain features or behaviors, so you get the output you want, like this:
my $result = $ftl->some_method_call( arg1, arg2, { options hashref } ); # ^^^^^^^^^^^^^^^ #
A couple of real examples would look like this:
$ftl->write_file( '/some/file.txt', 'Hello World!', { mode => 'append' } ); # ^^^^^^^^^^^^^^^^ # $ftl->list_dir( '/home/dangerian' => { recurse => 1, files_only => 1 } ); # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #
Managing potential errors is a big part of Perl IO. File::Util gives you several options. In fact, every single call to a File::Util method which accepts an "options hashref" can also include an error handling directive. File::Util has some pre-defined error handling behaviors that you can choose from, or you can supply your own error handler routine. This is accomplished via the "onfail" option.
As an added convenience, when you use this option with the File::Util constructor method, it sets the default error handling policy for all failures; in other words, you can set up one error handler for everything and never have to worry about it after that.
# Set every error to cause a warning instead of dying by default my $ftl = File::Util->new( { onfail => 'warn' } ); $ftl->write_file( 'C:\\' => 'woof!' ); # now this call will warn and not die
The predefined "onfail" behaviors and their syntaxes are covered below.
Example:
my $ftl = File::Util->new( ... { onfail => 'die' } );
Example:
my $content = File::Util->load_file( ... { onfail => 'zero' } );
Note: This option usually makes more practical sense than "onfail => 'zero'"
Example:
my $handle = File::Util->open_handle( ... { onfail => 'undefined' } );
Example:
my $write_ok = File::Util->write_file( ... { onfail => 'warn' } );
Example:
my @files = File::Util->list_dir( ... { onfail => 'message' } );
The subroutine you specify will receive two arguments as its input in "@_". The first will be the text of the error message, and the second will be a stack trace in text format. You can send them to a logger, to your sysadmin in an email alert, or whatever you like-- because it is *your* error handler.
WARNING! If you do not call "die" or "exit" at the end of your error handler, File::Util will NOT exit, but continue to execute. When you opt to use this feature, you are fully responsible for your process' error handling and post-error execution.
Examples using the constructor:
# step 1) define your custom error handler sub politician_error_handler { my ( $err, $stack ) = @_; # do stuff like ... $logger->debug( $stack ); die 'We neither confirm nor deny that an IO error has happened.'; } # step 2) apply your error handler my $ftl = File::Util->new( { onfail => \&politician_error_handler } ); -OR- # Define and apply your error handler in one step: my $ftl = File::Util->new( { onfail => sub { my ( $err, $stack ) = @_; # do stuff ... } } );
Examples in individual method calls:
$ftl->write_file( 'greedo' => 'try bargain' => { onfail => \&shoot_first } ); my $file_handle = $ftl->open_handle( '/this/might/not/work' => { onfail => sub { warn "Couldn't open first choice, trying a backup plan..."; return $ftl->open_handle( '/this/one/should/work' ); } } );
When things go wrong, sometimes it's nice to get as much information as possible about the error. In "File::Util", you incur no performance penalties by enabling more verbose error messages. In fact, you're encouraged to do so.
You can globally enable diagnostic messages (for every "File::Util" object you create), or on a per-object basis, or even on a per-call basis when you just want to diagnose a problem with a single method invocation. Here's how:
use File::Util qw( :diag );
my $ftl = File::Util->new( diag => 1 );
$ftl->diagnostic( 1 ); # turn diagnostic mode on # ... do some troubleshooting ... $ftl->diagnostic( 0 ); # turn diagnostic mode off
$ftl->load_file( 'abc.txt' => { diag => 1 } );
Note: In the past, some of the methods listed would state that they were autoloaded methods. This mechanism has been changed in favor of more modern practices, in step with the evolution of computing over the last decade since File::Util was first released.
Methods listed in alphabetical order.
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()"
+-------------------------+----------+--------------------+----------------+ | 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 | +-------------------------+----------+--------------------+----------------+
Note: Perl tries to support or emulate flock whenever it can via available system calls, namely "flock"; "lockf"; or with "fcntl".
When called with a true or false value as its single argument, this tells the File::Util object whether or not it should enable diagnostic error messages in the event of a failure. A true value indicates that the File::Util object will enable diagnostic mode, and a false value indicates that it will not. The default setting for "diagnostic()" is 0 (NOT enabled.)
see also DIAGNOSTICS
Works just like "strict_path", except that instead of returning "undef" when the argument passed in doesn't look like a path, it will return a default string instead. The default string returned will either be the built-in default path, or the string you specify as a second argument to this method.
The default string returned by this method is '.' . SL (see SL)
This means that on windows, the built-in default would be ".\" whereas on a POSIX-compliant system (Linux, UNIX, Mac, etc) you would get "./"
see also strict_path)
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.
The keywords and their definitions appear below; the order of keywords returned is the same as the order in which the are listed here:
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 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.
This setting can be dynamically changed at any point in your code by calling this method as desired.
The default behavior of File::Util is to try and obtain an exclusive lock on all file opens (if supported by your operating system). If a lock cannot be obtained, File::Util will throw an exception and exit.
If you want to change that behavior, this method is the way to do it. One common situation is for someone to want their code to first try for a lock, and failing that, to wait until one can be obtained. If that's what you want, see the examples after the keywords list below.
Recognized keywords:
Examples:
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 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 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.
Note that this is one of File::Util's most robust methods, and can be very useful. It can be used as a higher order function (accepting callback subrefs), and can be used for advanced pattern matching against files. It can also return a hierarchical data structure of the file tree you ask it to walk.
See the File::Util::Manual::Examples for several useful ways to use "list_dir()".
Syntax example to recursively return a list of subdirectories in directory "dir_name":
my @dirs = $f->list_dir( 'dir_name' => { dirs_only => 1, recurse => 1 } );
When you create a callback function, the File::Util will pass it four arguments in this order: The name of the current directory, a reference to a list of subdirectories in the current directory, a reference to a list of files in the current directory, and the depth (positive integer) relative to the directory you provided as your first argument to "list_dir()". This means if you pass in a path such as "/var/tmp", that "/var/tmp" is at a depth of 0, "/var/tmp/foo" is 1 deep, and so on down through the "/var/tmp" directory.
Remember that the code in your callback gets executed in real time, as list_dir() is walking the directory tree. Consider this example:
# Define a subroutine to print the byte size and depth of all files in a # directory, designed to be used as a callback function to list_dir() sub filesize { my ( $selfdir, $subdirs, $files, $depth ) = @_; print "$_ | " . ( -s $_ ) . " | $depth levels deep\n" for @$files; } # Now list directory recursively, invoking the callback on every recursion $f->list_dir( './droids' => { recurse => 1, callback => \&filesize } ); # Output would look something like # # ./droids/by-owner/luke/R2.spec | 1024 | 3 deep # ./droids/by-owner/luke/C2P0.spec | 2048 | 3 deep # ./droids/by-boss/dooku/Grievous.spec | 4096 | 3 deep # ./droids/by-series/imperial/sentries/R5.spec | 1024 | 4 deep # # Depth breakdown # # level 0 => ./droids/ # level 1 => ./droids/by-owner/ # level 1 => ./droids/by-boss/ # level 1 => ./droids/by-series/ # level 2 => ./droids/by-owner/luke/ # level 2 => ./droids/by-boss/dooku/ # level 2 => ./droids/by-series/imperial/ # level 3 => ./droids/by-series/imperial/sentries/
Another way to use callbacks is in combination with closures, to "close around" a variable or variables defined in the same scope as the callback. A demonstration of this technique is shown below:
{ my $size_total; my $dir = 'C:\Users\superman\projects\scripts_and_binaries'; # how many total bytes are in all of the executable files in $dir $f->list_dir( $dir => { callback => sub { my ( $selfdir, $subdirs, $files, $depth ) = @_; $size_total += -s $_ for grep { -B $_ } @$files; } } ); print "There's $size_total bytes of binary files in my projects dir."; }
For compatibility reasons, you can use ""maxdepth"" without the underscore instead, and get the same functionality.
You get a performance boost at the sacrifice of a little "safety checking".
The bigger your file tree, the more performance gains you see.
This option has no effect on Windows. (see perldoc -f stat)
**By default, items returned by the call to this method are alphabetically sorted in a case-insensitive manner, such that "Zoo.txt" comes before "alligator.txt". This is also the way files are listed at the system level on most operating systems.
However, if you'd like the directory contents returned by this method to be sorted without regard to case, use this option. That way, "alligator.txt" will come before "Zoo.txt".
*Note: When using this option, the "files_only" and "dirs_only" options are ignored, but you can still specify things like a "max_depth" argument, however. Note also that you need to specifically call this with the "recurse" or "recurse_fast" option or you will only get a single-level tree structure.
One quick example:
my $tree = $ftl->list_dir( '/tmp' => { as_tree => 1, recurse => 1, } ); # output would look something like this if you Data::Dumper'd it { '/' => { '_DIR_PARENT_' => undef, '_DIR_SELF_' => '/', 'tmp' => { '_DIR_PARENT_' => '/', '_DIR_SELF_' => '/tmp', 'hJMOsoGuEb' => { '_DIR_PARENT_' => '/tmp', '_DIR_SELF_' => '/tmp/hJMOsoGuEb', 'a.txt' => '/tmp/hJMOsoGuEb/a.txt', 'b.log' => '/tmp/hJMOsoGuEb/b.log', 'c.ini' => '/tmp/hJMOsoGuEb/c.ini', 'd.bat' => '/tmp/hJMOsoGuEb/d.bat', 'e.sh' => '/tmp/hJMOsoGuEb/e.sh', 'f.conf' => '/tmp/hJMOsoGuEb/f.conf', 'g.bin' => '/tmp/hJMOsoGuEb/g.bin', 'h.rc' => '/tmp/hJMOsoGuEb/h.rc', } } } }
When using this option, the hashref you get back will have certain metadata entries at each level of the hierarchy, namely there will be two special keys: "_DIR_SELF", and "_DIR_PARENT_". Their values will be the name of the directory itself, and the name of its parent, respectively.
That metadata can be extremely helpful when iterating over and parsing the hashref later on, but if you don't want the metadata, include the "dirmeta" option and set it to a zero (false) value as shown below:
my $tree = $ftl->list_dir( '/some/dir' => { as_tree => 1, recurse => 1, dirmeta => 0, } );
**Remember: the "as_tree" doesn't recurse into subdirectories unless you tell it to with "recurse => 1"
Regular expressions can be provided as a single argument value, or a specifically crafted hashref designating a list of patterns to match against in either an "or" manner, or an "and"ed cumulative manner.
Some short examples of proper syntax will be provided after the list of matching options below.
**If you experience a big slowdown in directory listings while using regular expressions, check to make sure your regular expressions are properly written and optimized. In general, directory listings should not be slow or resource-intensive. Badly-written regular expressions will result in considerable slowdowns and bottlenecks in any application.
Use the "files_only" option in combination with this matching parameter to exclude the preceding directory names.
*NOTE: Bear in mind that just because you tell "list_dir()" to match each directory against the regex(es) you specify here, that doesn't mean you are telling it to only show directories in its results. You will get file names in matching directories included in the results as well, unless you combine this with the "dirs_only" option.
my @files = $f->list_dir( '../notes' => { files_match => qr/\.txt$/i, files_only => 1 } ); my @dirs = $f->list_dir( '/var' => { dirs_match => qr/log|spool/i, recurse => 1, dirs_only => 1, } ); my @dirs = $f->list_dir( '/home' => { path_matches => qr/Desktop/, recurse => 1, dirs_only => 1, } ); my @files = $f->list_dir( '/home/tommy/projects' => { parent_matches => qr/^\.git$/, recurse => 1, } );
A multiple-argument matching examples with OR
my @files = $f->list_dir( 'C:\Users\Billy G' => { parent_matches => { or => [ qr/Desktop/, qr/Pictures/ ] } recurse => 1, } ); # ... same concepts apply to "files_match", "dirs_match", # and "parent_matches" filtering
Multiple-argument matching examples with AND
my @files = $f->list_dir( '/home/leia' => { parent_matches => { and => [ qr/Anakin/, qr/Amidala/ ] } recurse => 1, } ); my @files = $f->list_dir( '/home/mace' => { path_matches => { and => [ qr/^(?!.*dark.side)/i, qr/[Ff]orce/ ] } recurse => 1, } ); # ... same concepts apply to "files_match" and "dirs_match" filtering
**When you specify regexes for more than one filter type parameter, the patterns are AND'ed together, as you'd expect, and all matching criteria must be satisfied for a successful overall match.
my @files = $f->list_dir( '/var' => { dirs_match => { or => [ qr/^log$/, qr/^lib$/ ] }, files_match => { or => [ qr/^syslog/, qr/\.isam$/i ] }, parent_matches => qr/[[:alpha:]]+/ path_matches => qr/^(?!.*home)/, recurse => 1, files_only => 1, }
Negative matches (when you want to NOT match something) - use Perl!
As shown in the File::Util::Manual::Examples, Perl already provides support for negated matching in the form of "zero-width negative assertions". (See perlre for details on how they work). Use syntax like the regular expressions below to match anything that is NOT part of the subpattern.
# match all files with names that do NOT contain "apple" (case sensitive) my @no_apples = $f->list_dir( 'Pictures/fruit' => { files_match => qr/^(?!.*apple)/ } ); # match all files that that do NOT end in *.mp3 (case INsensitive) # also, don't match files that end in *.wav either my @no_music = $f->list_dir( '/opt/music' => { files_match => { and => [ qr/^(?!.*mp3$)/i, qr/^(?!.*wav$)/i ] } );
The type of data structure returned is determined by the optional data-type option parameter. Only one option at a time may be used for a given call to this method. Recognized options are listed below.
my $files_hash_ref = $f->load_dir( $dirname ); # default (hashref) -OR- my $files_list_ref = $f->load_dir( $dirname => { as_listref => 1 } ); -OR- my @files = $f->load_dir( $dirname => { as_list => 1 } );
This is useful in situations where you don't care what the filenames were and you just want a list of file contents.
"load_dir()" does not recurse or accept matching parameters, etc. It's an effective tool for loading up things like a directory of template files on a web server, or to store binary data streams in memory. Use it however you like.
However, if you do want to load files into a hashref/listref or array while using the advanced features of "list_dir()", just use list_dir to return the files and map the contents into your variable:
my $hash_ref = {}; %$hash_ref = map { $_ => $ftl->load_file( $_ ) } $ftl->list_dir( $dir_name => { advanced options... } );
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 read_limit()) entry below will be applied to the individual files opened by this method as well. Adjust the read limit as necessary.
Example usage:
my $templates = $f->load_dir( 'templates/stock-ticker' );
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', };
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" option (see below).
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.
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.
You need Perl 5.8 or better to use 'utf8' or your program will fail with an error message.
Example Usage:
my $encoded_data = $ftl->load_file( 'encoded.txt' => { binmode => 'utf8' } );
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 read_limit()) entry below will be applied to the files opened by this method. Adjust the read limit as necessary either by overriding (using the 'read_limit' option above), or by adjusting the global value for your File::Util object with the provided read_limit() object method.
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 oct 777, combined with the current user's umask.
Upon successful creation of the [new directory name], the [new directory name] is returned to the caller.
$f->make_dir( '/home/jspice' => oct 755 => { if_not_exists => 1 } );
If this option is enabled 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" option 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.
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.
(see also: list_dir)
(see also: abort_depth())
You can supply an "onfail" handler to nearly any function in File::Util, but when you do so for the "new()" constructor, you are setting the default.
Acceptable values are all covered in the ERROR HANDLING section (above), along with proper syntax and example usage.
This works exactly the same as it does when you specify an "onfail" handler to the constructor method (see also "new").
The syntax and keywords available to use for this method are already discussed above in the ERROR HANDLING section, so refer to that for in-depth details.
Here are some examples:
$ftl->onfail( 'die' ); $ftl->onfail( 'zero' ); $ftl->onfail( 'undefined' ); $ftl->onfail( 'message' ); $ftl->onfail( \&subroutine_reference ); $ftl->onfail( sub { my ( $error, $stack_trace ) = @_; ... } );
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 new) or by using the "no_lock" option 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 portability in 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 turns 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" option, 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. The only obvious exception would be if you are working with files on a network-mounted filesystem like NFS or SMB (CIFS), in which case locking can be buggy.
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 oct 777. The bitmask is combined with the current user's umask, whether you specify a value or not. This is a function of Perl, not File::Util.
If specified, the bitmask must be supplied in the form of an octal number as 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.
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 an error. If all directories preceding the name of the file already exist, the dbitmask argument has no effect and is silently ignored.
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" option. Remember that these won't work unless you use that option, 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:
Remember to use "sysread()" and not plain "read()" when reading those "sysopen()"'d filehandles!
You need Perl 5.8 or better to use "utf8" or your program will fail with an error message.
Example Usage:
$ftl->open_handle( 'encoded.txt' => { binmode => 'utf8' } );
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".
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 method is optimized for speed and returns anything that could possibly be a file path, even if that means the path is actually "foo.bar" if you passed it such an argument. Technically, you could indeed have a directory named "blaster.txt", so this method doesn't distinguish between strings that look like file names and ones that don't.
If you want one that does, you need to use "strict_path()" instead. (see strict_path)
This method doesn't divine or detect any information about the path, it simply manipulates the string value. It doesn't map it to any real filesystem object. It doesn't matter whether or not the file/path named in the input string exists or not.
If you'd like to get a default path string returned instead of "undef", then you want to use the "default_path()" method instead.
(see also return_path and default_path)
Given "/kessel/run/12/parsecs", it returns "parsecs"
Given "C:\you\scoundrel", it returns "scoundrel"
Returns 1 if successful. If unsuccessful, fails with an error.
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" option 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.
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.
You may have to explicitly disable file locking completely.
# get some content (a string returned from a function call, perhaps) my $answer = ask_commissioner( 'Can he be trusted?' ); $ftl->write_file( 'Harvey_Dent.txt' => $answer ); -OR- # get some binary content, maybe a picture... my $binary_data = get_mugshot( alias => 'twoface' ); $ftl->write_file( 'suspect.png' => $binary_data => { binmode => 1 } ); -OR- # write a file with UTF-8 encoding (unicode character support) $ftl->write_file( 'encoded.txt' => $encoded_data => { binmode => 'utf8' } ); -OR- $ftl->write_file( { file => '/gotham/city/ballots/Bruce_Wayne.txt', content => 'Vote for Harvey!', bitmask => oct 600, # <- secret ballot file permissions } );
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 oct 777. The bitmask is combined with the current user's umask, whether you specify a value or not. This is a function of Perl, not File::Util.
[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 enable the "binmode => 1" option for binary streams, and be sure to specify a value of "binmode => 'utf8'" for UTF-8 encoded data.
NOTE: that you will need Perl version 5.8 or better to use the 'utf8' feature, or your program will fail with an error.
If specified, the bitmask must be supplied in the form of an octal number, as 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 with an error if not successful.
Any non-existent directories in the path preceding the actual file name will be automatically (and silently - no warnings) created for you and 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 a problem while trying to create any preceding directories, the failure results in a fatal error. If all directories preceding the name of the file already exist, the dbitmask argument has no effect and is silently ignored.
You need Perl 5.8 or better to use "utf8" or your program will fail with an error message.
Example Usage:
$ftl->write_file( 'encoded.txt' => $encoded_data => { binmode => 'utf8' } );
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" enabled.
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.
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::Util::Cookbook, File::Util::Manual::Examples, File::Util
2022-11-29 | perl v5.36.0 |