Name
File::DataClass::IO - Better IO syntax
Version
This document describes version v0.31.$Rev: 1 $ of File::DataClass::IO
Synopsis
use File::DataClass::IO;
# Read the first line of a file and chomp the result
my $line = io( 'path_name' )->chomp->getline;
# Write the line to file set permissions, atomic update and fcntl locking
io( 'path_name' )->perms( oct '0644' )->atomic->lock->print( $line );
# Constructor methods signatures
my $obj = io( $obj ); # clone
my $obj = io( $obj, $hash_ref ); # clone and merge
my $obj = io( $hash_ref );
my $obj = io( $name ); # coderef, object ref, arrayref or string
my $obj = io( $name, $hash_ref );
my $obj = io( $name, $mode );
my $obj = io( $name, $mode, $perms );
my $obj = io( name => $name, mode => $mode, ... );
Description
This is a simplified re-write of IO::All with additional functionality from IO::AtomicFile. Provides the same minimalist API but without the heavy OO overloading. Only has methods for files and directories
Configuration and Environment
File::DataClass::Constants has a class attribute Exception_Class
which defaults to File::DataClass::Exception. Set this attribute to the classname used by the "_throw" method
Defines the following attributes;
autoclose
-
Defaults to true. Attempts to read past end of file will cause the object to be closed
io_handle
-
Defaults to undef. This is set when the object is actually opened
is_open
-
Defaults to false. Set to true when the object is opened
is_utf8
-
Boolean should set to true if the file is
UTF8
encoded. Defaults for false mode
-
File open mode. Defaults to 'r' for reading. Can any one of; 'a', 'a+', 'r', 'r+', 'w', or 'w+'
name
-
Defaults to undef. This must be set in the call to the constructor or soon after. Can be a
coderef
, anobjectref
, anarrayref
, or a scalar. After coercion to a scalar leading tilde expansion takes place sort
-
Boolean defaults to true. If the IO object is a directory then sort the listings
type
-
Defaults to undefined. Set by the "dir" and "file" methods to
dir
andfile
respectively. The "dir" method is called by the "next" method. The "file" method is called by the "assert_open" method if thetype
attribute is undefined
Subroutines/Methods
If any errors occur the throw
method in the "EXCEPTION_CLASS" in File::DataClass::Constants is called
Methods beginning with an _ (underscore) are deemed private and should not be called from outside this package
BUILDARGS
Constructs the attribute hash passed to the constructor method. The constructor can be called with these method signatures:
- $io = File::DataClass::IO->new( { name => $pathname, ... } )
-
A hash ref containing a list of key value pairs which are the object's attributes (where
name
is the pathname,mode
the read/write/append flag, andperms
the permissions on the file) - $io = File::DataClass::IO->new( $pathname, [ $mode, $perms ] )
-
A list of values which are taken as the pathname, mode and permissions. The pathname can be an array ref, a coderef, a scalar, or an object that stringifies to a scalar path
- $io = File::DataClass::IO->new( $object_ref )
-
An object which is a File::DataClass::IO
abs2rel
$path = io( 'path_to_file' )->abs2rel( 'optional_base_path' );
Makes the pathname relative via a call to abs2rel. Returns a path
absolute
$io = io( 'relative_path_to_file' )->absolute( 'optional_base_path' );
Calls "rel2abs" without an optional base path. Returns an IO object ref
all
$lines = io( 'path_to_file' )->all;
For a file read all the lines and return them as a single scalar
@entries = io( 'path_to_directory' )->all( $level );
For directories returns a list of IO objects for all files and subdirectories. Excludes "curdir" in File::Spec and "updir" in File::Spec
Takes an optional argument telling how many directories deep to search. The default is 1. Zero (0) means search as deep as possible The default can be changed to zero by calling the "deep" method
The filter method can be used to limit the results
The items returned are sorted by name unless "sort"(0) is used
all_dirs
@entries = io( 'path_to_directory' )->all_dirs( $level );
Like ->all( $level )
but returns only directories
all_files
@entries = io( 'path_to_directory' )->all_files( $level );
Like ->all( $level )
but returns only files
append
io( 'path_to_file' )->append( $line1, $line2, ... );
Opens the file in append mode and calls "print" with the passed args
appendln
io( 'path_to_file' )->appendln( $line, $line2, ... );
Opens the file in append mode and calls "println" with the passed args
assert
$io = io( 'path_to_file' )->assert;
Sets the private attribute _assert
to true. Causes the open methods to create the path to the directory before the file/directory is opened
assert_dirpath
$dir_name = io( 'path_to_file' )->assert_dirpath;
Create the given directory if it doesn't already exist
assert_filepath
$io = io( 'path_to_file' )->assert_filepath;
Calls "assert_dirpath" on the directory part of the full pathname
assert_open
$io = io( 'path_to_file' )->assert_open( $mode, $perms );
Calls "file" to default the type if its not already set and then calls "open" passing in the optional arguments
atomic
$io = io( 'path_to_file' )->atomic;
Implements atomic file updates by writing to a temporary file and then renaming it on closure. This method uses the pattern in the _atomic_infix
attribute to compute the temporary pathname
atomic_suffix
$io = io( 'path_to_file' )->atomic_suffix( '.tmp' );
Syntactic sugar. See "atomix_infix"
atomic_infix
$io = io( 'path_to_file' )->atomic_infix( 'B_*' );
Defaults to B_*
(prefix). The *
is replaced by the filename to create a temporary file for atomic updates. If the value does not contain a *
then the value is appended to the filename instead (suffix). Attribute name _atomic_infix
If the value contains %P
it will be replaced with the process id
If the value contains %T
it will be replaces with the thread id
basename
$dirname = io( 'path_to_file' )->basename( @suffixes );
Returns the File::Basename basename
of the passed path
binary
$io = io( 'path_to_file' )->binary;
Sets binary mode
binmode
$io = io( 'path_to_file' )->binmode( $layer );
Sets binmode to the given layer
block_size
$io = io( 'path_to_file' )->block_size( 1024 );
Defaults to 1024. The default block size used by the "read" method
buffer
The internal buffer used by "read" and "write"
_build__dir_pattern
Returns the pattern that will match against the current or parent directory
canonpath
$canonpath = io( '././path_to_file' )->canonpath;
Returns the canonical path for the object
catdir
$io = io( 'path_to_directory' )->catdir( 'additional_directory_path' );
Create a new IO directory object by concatenating this objects pathname with the one that is supplied
catfile
$io = io( 'path_to_directory' )->catfile( 'additional_file_path' );
Create a new IO file object by concatenating this objects pathname with the one that is supplied
chmod
$io = io( 'path_to_file' )->chmod( '0644' );
Changes the permission on the file to the selected value. Permission values can be either octal or string
chomp
$io = io( 'path_to_file' )->chomp;
Causes input lines to be chomped when "getline" or "getlines" are called
chown
$io = io( 'path_to_file' )->chown( $uid, $gid );
Changes user and group ownership
clear
$io->clear
Set the contents of the internal buffer to the null string
close
$io->close;
Close the file or directory handle depending on type
If the temporary atomic file exists, renames it to the original filename. Unlocks the file if it was locked. Closes the file handle
copy
$dest_obj = io( 'path_to_file' )->copy( $destination_path_or_object );
Copies the file to the destination. The destination can be either a path or and IO object. Returns the destination object
cwd
$current_working_directory = io()->cwd;
Returns the current working directory wrapped in a File::DataClass::IO object
deep
@files = io( 'path_to_root_of_tree' )->deep->all_files
Changes the default level for the "all" methods to zero so that the whole directory tree is searched
delete
Deletes the atomic update temporary file if it exists. Then calls "close"
delete_tmp_files
$io = io( $tempdir )->delete_tmp_files( $template );
Delete temporary files for this process (temporary file names include the process id). Temporary files are stored in the $tempdir
. Can override the template filename pattern if required
DEMOLISH
If this is an atomic file update calls the "delete" method. If the object is still open it calls the "close" method
dir
Initialises the current object as a directory
dirname
$dirname = io( 'path_to_file' )->dirname;
Returns the File::Basename dirname
of the passed path
empty
$bool = io( 'path_to_file' )->empty;
Returns true if the pathname exists and is zero bytes in size
encoding
$io = io( 'path_to_file' )->encoding( $encoding );
Apply the given encoding to the open file handle and store it on the _encoding
attribute
error_check
Tests to see if the open file handle is showing an error and if it is it "throw"s an eIOError
exists
$bool = io( 'path_to_file' )->exists;
Returns true if the pathname exists
file
Initializes the current object as a file
filename
$filename = io( 'path_to_file' )->filename;
Returns the filename part of pathname
filepath
$dirname = io( 'path_to_file' )->filepath;
Returns the directory part of pathname
filter
$io = io( 'path_to_directory' )->filter( sub { m{ \A A_ }msx } );
Takes a subroutine reference that is used by the "all" methods to filter which entries are returned. Called with $_
set to each pathname in turn. It should return true if the entry is wanted
getline
$line = io( 'path_to_file' )->getline;
Asserts the file open for reading. Get one line from the file handle. Chomp the line if the _chomp
attribute is true. Check for errors. Close the file if the autoclose
attribute is true and end of file has been read past
getlines
@lines = io( 'path_to_file' )->getlines;
Like "getline" but calls "getlines" on the file handle and returns an array of lines
_init
Sets default values for some attributes, takes two optional arguments; type
and name
io
$io = io( 'path_to_file' );
Subroutine exported by default. Returns a new IO object
is_absolute
$bool = io( 'path_to_file' )->is_absolute;
Return true if the pathname is absolute
is_dir
$bool = io( 'path_to_file' )->is_dir;
Tests to see if the IO object is a directory
is_executable
$bool = io( 'path_to_file' )->is_executable;
Tests to see if the IO object is executable
is_file
$bool = io( 'path_to_file' )->is_file;
Tests to see if the IO object is a file
is_link
$bool = io( 'path_to_file' )->is_link;
Returns true if the IO object is a symbolic link
is_readable
$bool = io( 'path_to_file' )->is_readable;
Tests to see if the IO object is readable
is_reading
$bool = io( 'path_to_file' )->is_reading;
Returns true if this IO object is in one of the read modes
is_writable
$bool = io( 'path_to_file' )->is_writable;
Tests to see if the IO
object is writable
iterator
$code_ref = io( 'path_to_directory' )->iterator;
When called the coderef iterates over the directory listing. If deep
is true then the iterator will visit all subdirectories. If no_follow
is true then symbolic links to directories will no be followed. A "filter" may also be applied
length
$positive_int = io( 'path_to_file' )->length;
Returns the length of the internal buffer
lock
$io = io( 'path_to_file' )->lock;
Causes "_open_file" to set a shared flock if its a read an exclusive flock for any other mode
mkdir
io( 'path_to_directory' )->mkdir;
Create the specified directory
mkpath
io( 'path_to_directory' )->mkpath;
Create the specified path
move
$dest_obj = io( 'path_to_file' )->move( $destination_path_or_object );
Moves the file to the destination. The destination can be either a path or and IO object. Returns the destination object
next
$io = io( 'path_to_directory' )->next;
Calls "dir" if the type
is not already set. Asserts the directory open for reading and then calls "read_dir" to get the first/next entry. It returns an IO object for that entry
no_follow
$io = io( 'path_to_directory' )->no_follow;
Defaults to false. If set to true do not follow symbolic links when performing recursive directory searches
open
$io = io( 'path_to_file' )->open( $mode, $perms );
Calls either "_open_dir" or "_open_file" depending on type. You do not usually need to call this method directly. It is called as required by "assert_open"
_open_dir
If the _assert
attribute is true calls "assert_dirpath" to create the directory path if it does not exist. Opens the directory and stores the handle on the io_handle
attribute
_open_file
Opens the pathname with the given mode and permissions. Calls "assert_filepath" if assert
is true. Mode defaults to the mode
attribute value which defaults to r
. Permissions defaults to the _perms
attribute value. Throws eCannotOpen
on error. If the open succeeds "set_lock" and "set_binmode" are called
parent
$parent_io_object = io( 'path_to_file_or_directory' )->parent( $count );
Return "dirname" as an IO object. Repeat $count
times
pathname
$pathname = io( 'path_to_file' )->pathname;
Returns then name
attribute
perms
$io = io( 'path_to_file' )->perms( $perms );
Stores the given permissions on the _perms
attribute
$io = io( 'path_to_file' )->print( $line1, $line2, ... );
Asserts that the file is open for writing and then prints passed list of args to the open file handle. Throws ePrintError
if the print
statement fails
println
$io = io( 'path_to_file' )->println( $line1, $line2, ... );
Calls "print" appending a newline to each of the passed list args that doesn't already have one
read
$bytes_read = io( 'path_to_file' )->read( $buffer, $length );
Asserts that the pathname is open for reading then calls "read" on the open file handle. If called with args then these are passed to the "read". If called with no args then the internal buffer is used instead. Returns the number of bytes read
read_dir
@io_object_refs = io( 'path_to_directory' )->read_dir;
$io = io( 'path_to_directory' )->read_dir;
If called in an array context returns a list of all the entries in the directory. If called in a scalar context returns the first/next entry in the directory
rel2abs
$path = io( 'relative_path_to_file' )->rel2abs( 'optional_base_path' );
Makes the pathname absolute. Returns a path
relative
$relative_path = io( 'path_to_file' )->relative;
Calls "abs2rel" without an optional base path
reset
$io = io( 'path_to_file' )->reset;
Calls "close" and resets chomp
to false
rmdir
$io = io( 'path_to_directory' )->rmdir;
Remove the directory
rmtree
$number_of_files_deleted = io( 'path_to_directory' )->rmtree;
Remove the directory tree
seek
$io = io( 'path_to_file' )->seek( $position, $whence );
Seeks to the selected point in the file
separator
$io = io( 'path_to_file' )->separator( $RS );
Set the record separator used in calls to getlines and chomp
set_binmode
$io = io( 'path_to_file' )->set_binmode;
Sets the currently selected binmode on the open file handle
set_lock
$io = io( 'path_to_file' )->set_lock;
Calls "flock" on the open file handle
slurp
$lines = io( 'path_to_file' )->slurp;
@lines = io( 'path_to_file' )->slurp;
In a scalar context calls "all" and returns its value. In an array context returns the list created by splitting the scalar return value on the system record separator. Will chomp each line if required
splitdir
@directories = io( 'path_to_directory' )->splitdir;
Proxy for "splitdir" in File::Spec
splitpath
($volume, $directories, $file) = io( 'path_to_file' )->splitpath;
Proxy for "splitpath" in File::Spec
stat
$stat_hash_ref = io( 'path_to_file' )->stat;
Returns a hash of the values returned by a "stat" call on the pathname
substitute
$io = io( 'path_to_file' )->substitute( $search, $replace );
Substitutes $search
regular expression for $replace
string on each line of the given file
tempfile
$io = io( 'path_to_temp_directory' )->tempfile( $template );
Create a randomly named temporary file in the name
directory. The file name is prefixed with the creating processes id and the temporary directory defaults to /tmp
_throw
io( 'path_to_file' )->_throw( error => 'message', args => [] );
Exposes the throw
method in the exception class
touch
$io = io( 'path_to_file' )->touch( $time );
Create a zero length file if one does not already exist with given file system permissions which default to 0644 octal. If the file already exists update it's last modified datetime stamp. If a value for $time
is provided use that instead if the CORE::time
unlink
$bool = io( 'path_to_file' )->unlink;
Delete the specified file. Returns true if successful
unlock
$io = io( 'path_to_file' )->unlock;
Calls flock
on the open file handle with the LOCK_UN
option to release the Fcntl lock if one was set. Called by the "close" method
utf8
$io = io( 'path_to_file' )->utf8;
Sets the current encoding to utf8
write
$bytes_written = io( 'pathname' )->write( $buffer, $length );
Asserts that the file is open for writing then write the $length
bytes from $buffer
. Checks for errors and returns the number of bytes written. If $buffer
and $length
are omitted the internal buffer is used. In this case the buffer contents are nulled out after the write
Diagnostics
None
Dependencies
Incompatibilities
On MSWin32
and Cygwin
platforms there is a race condition when the atomic write option is used. This is caused by the filesystem which does not allow an open file to be renamed
On MSWin32
and Cygwin
platforms if the move in atomic write option fails a copy and delete is attempted. This will throw if the copy fails. These platforms deny rename rights on newly created files by default
On MSWin32
and Cygwin
platforms binmode
is automatically enabled
Bugs and Limitations
There are no known bugs in this module. Please report problems to the address below. Patches are welcome
Acknowledgements
- Larry Wall
-
For the Perl programming language
- Ingy döt Net <ingy@cpan.org>
-
For IO::All from which I took the API and some tests
- Path::Tiny
-
Lifted the following features; iterator, tilde expansion, thread id in atomic file name, not following symlinks and some tests
Author
Peter Flanigan, <pjfl@cpan.org>
License and Copyright
Copyright (c) 2014 Peter Flanigan. All rights reserved
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic
This program is distributed in the hope that it will be useful, but WITHOUT WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE