NAME
File::PathInfo - oo access to path variables stat data about a file on disk
SYNOPSIS
use File::PathInfo;
my $f = new File::PathInfo;
$f->set('/home/myself/public_html/folder/stew.txt) or die('file does not exist');
$f->is_text; # returns 1
$f->ext; # returns 'txt'
$f->abs_loc; # returns '/home/myself/public_html/folder'
DESCRIPTION
This provides an object oriented interface to things you want to know about a file, such as extension, absolute path, relative path, size, filename (without extension), etc. It is a sort of swissarmy knife of file info.
A lot of times you need to know a file's absolute path, it's absolute location, maybe it's relative location to something else (like DOCUMENT ROOT), then you need to maybe know the relative path and relative location for a file. You need to know if a file is a directory, what it's extension is. You can commonly use regexes to do this.
This module provides commonly needed variables.
Works with relative paths like in a website too:
use File::PathInfo;
my $f = new File::PathInfo;
$f->set('folder/stew.txt) or die('file does not exist');
$f->abs_path; # returns '/home/myself/public_html/folder/stew.txt'
$f->rel_path; # returns 'folder/stew.txt'
$f->rel_loc; # returns 'folder'
$f->is_in_DOCUMENT_ROOT; # returns 1
Also safeguards from cgi accessing files outside of document root
use File::PathInfo;
my $f = new File::PathInfo;
$f->set('/home/myself/stew.txt) or die('file does not exist');
$f->rel_path; # throws exception and complains that it is not in document root
You can define also, that document root is something else. To assure the files you are dealing with remain in a certain part of the filesystem tree. Also lets you set a different document root, if you want an application to serve files in some other place, but you still want to restrict what the script can access to within that slice of the filesystem:
use File::PathInfo;
my $f = new File::PathInfo({ DOCUMENT_ROOT => '/home/myself/sharethese' });
$f->set('/home/myself/sharethese/stew.txt) or die('file does not exist');
$f->rel_path; # returns 'stew.txt'
Realize that for the rest of your cgi, ENV DOCUMENT ROOT is still your webshare, public html, etc. It's just that you can override for the object instance, what the DOCUMENT ROOT is.
By default if you want to get path info on a file that is not on disk, an exception is thrown. If you want to disable that:
use File::PathInfo({ check_exist => 0 });
my $f = new File::PathInfo;
$f->set('/home/myself/html/sty54wyw5/4y54yy4ew.txt') ;
$f->rel_path; # returns 'sty54wyw5/4y54yy4ew.txt'
Maybe this could be useful if you wanted to work with a path string that *was* present or *will be*.
Absolute path methods are accessible always. The relative path methods are accessible *if* you have DOCUMENT ROOT environment variable set or if you pass the argument DOCUMENT_ROOT to object constructor.
If you are using cgi, ENV DOCUMENT_ROOT is set when you call the program via http (the browser). But when you call the program via the cli (command line) it will likely not be set! This causes some programs to crash when you run then on the command line, and you scratch your head and ask 'how come?'. The same goes for the environment variable 'HOME', which is not set when you call your cgi script via http (browser) but is set if you call it via cli (the command line, shell access, etc.).
METHODS
new()
Argument is either a hash ref or an absolute or relative path to a file.
my $fi = new File::PathInfo;
$fi->set('/home/myself/html/file.txt');
# or
my $fi = new File::PathInfo('/home/myself/html/file.txt');
Optional parameters to constructor:
my $fi = new File::PathInfo({
DOCUMENT_ROOT => '/home/myself/html',
check_exist => 0,
time_format => 'yyyy/mm/dd hh::mm',
});
- 'check_exist'
-
Defaults to true. If a file does not exist, methods return undef.
- 'DOCUMENT_ROOT'
-
Set a different document root variable from the one currently on server. This variable must be set either in the server or via this argument if you will use the relative file path methods.
set()
Unless you provide an argument to the constructor, set() must be called. You can use set() to iterate through a list of paths. Argument is a relative or absolute file path.
$f->set('/tmp/trashdir'); # absolute path
$f->set('gfx/logo.gif'); # relative to DOCUMENT ROOT
$f->set('./thisfile.png'); # relative to current working directory
Method set()
returns abs path. If the file cannot be resolved to disk then it warns and returns undef. If you then call any methods, exceptions are thrown with Carp::croak.
You can do this too:
$f->set('/home/myself/html/documents/manual.pdf') or die( $File::PathInfo::errstr );
$f->set('documents/manual.pdf') or print "Location: 404.html\n\n" and exit;
Returns abs path resolved to item in question.
get_datahash()
Takes no argument. Returns all elements, in a hash.
Try it out:
#!/usr/bin/perl -w
use File::PathInfo;
use Smart::Comments '###';
my $f = new File::PathInfo;
$f->set '/home/bubba'
my $hash = $f->get_datahash;
### $hash
Prints out:
### $hash: {
### abs_loc => '/home',
### abs_path => '/home/bubba',
### atime => 1173859680,
### atime_pretty => '2007/03/14 04:08',
### blksize => 4096,
### blocks => 8,
### ctime => 1173216034,
### ctime_pretty => '2007/03/06 16:20',
### dev => 2049,
### filename => 'bubba',
### filename_only => 'bubba',
### filesize => '4096',
### filesize_pretty => '4k',
### gid => 0,
### ino => 3626597,
### is_binary => 1,
### is_dir => 1,
### is_file => 0,
### is_text => 0,
### is_topmost => 0,
### mode => 16877,
### mtime => 1173216034,
### mtime_pretty => '2007/03/06 16:20',
### nlink => 3,
### rdev => 0,
### size => '4096',
### uid => 0
### }
errstr()
Returns errot string or undef if no errors are present.
To check for errors you can query the error string.
$f->set('/home/myself/this') or die($f->errstr);
ABSOLUTE METHODS
The absolute path methods.
abs_loc()
Returns absolute location on disk. Everything but the filename, no trailing file delimiter (slash).
abs_path()
Returns absolute path on disk. Notice that all symlinks are resolved with Cwd::abs_path, so any /../ etc are gone.
filename()
Returns filename, no leading directories, no leading file delimiter (slash).
filename_only()
Returns filename without extension. '/home/myself/this.txt' would return 'this' Does not return undef.
ext()
Returns filename ext, if none found, returns undef.
RELATIVE METHODS
These methods are only available if a DOCUMENT ROOT is defined.
rel_path()
relative to DOCUMENT_ROOT
rel_loc()
location relative to DOCUMENT_ROOT
is_DOCUMENT_ROOT()
if this *is* the document root returns undef if DOCUMENT ROOT is not set.
is_topmost()
if the parent directory is document root. boolean. returns undef if DOCUMENT ROOT is not set.
is_in_DOCUMENT_ROOT()
does this file reside in the DOCUMENT_ROOT tree ? note that DOCUMENT_ROOT itself *is* the document root, does is not considered to be *in* the document root. this is partly for security reasons.
DOCUMENT_ROOT()
Returns doc root, returns undef if not set, or if it cant resolve to abs path on disk. You can override the DOCUMENT root like this:
my $fi = new File::PathInfo('./path/to/file.tmp',{ DOCUMENT_ROOT => '/home/myself' });
Doc root is also resolved for symlinks and . and .. etc.
Using a custom DOCUMENT_ROOT variable for the object instance does not alter the variable for other cgi programs, etc. Just for the object you created. It is only used internally, If this class is inherited, $ENV{DOCUMENT_ROOT} is whatever it is set at on the server. If you provide a different DOCUMENT_ROOT as an argument, $ENV{DOCUMENT_ROOT} still returns the server set variable. It is method DOCUMENT_ROOT() that returns the internally used value.
You do not have to provide a DOCUMENT_ROOT value to the constructor, the variable is not needed unless you use the relative path methods
Again, the order of priority to define what the DOCUMENT ROOT is for an instance of File::PathInfo is:
First, in argument to contructor
Second, if your environment variable DOCUMENT_ROOT is set.
You can also call DOCUMENT_ROOT_set()
DOCUMENT_ROOT_set()
argumnent is abs path to document root will warn if not a dir on disk
STAT METHODS
These methods ask useful things like, is the file a directory, is it binary, is it text, what is the mtime, etc. These methods load data on call, they can be expensive if you are looping through thousands of files. So don't worry because if you don't need them, they are not called. Using one or more of these methods makes one stat call only.
is_binary()
returns boolean true or false.
is_text()
returns boolean true or false.
is_dir()
returns boolean true or false.
is_file()
returns boolean true or false.
ctime()
atime()
mtime()
uid()
ino()
blksize()
blocks()
dev()
gid()
mode()
nlink()
rdev()
size()
filesize_pretty()
Returns filesize in k, with the letter k in the end returns 0k if filesize is 0 .
ctime_pretty()
atime_pretty()
mtime_pretty()
Returns these timestamps formatted to 'yyyy/mm/dd hh:mm' by default. To change the format, pass it as argument to object constructor as such:
my $r = new File::PathInfo({ time_format => 'yyyy_mm_dd' });
$r->set('/home/myself/archive1.zip');
$r->ctime_pretty; # now holds 1999_11_13
filesize()
Returns filesize in bites.
PROCEDURAL SUBROUTINES
None of these functions are exported by default. These subs are used by the oo methods internally, and you can use them in your code also by the normal import ways:
use File::PathInfo ':all';
use File::PathInfo qw(abs_path_n);
abs_path_n()
just like Cwd::abs_path() but, does not resolve symlinks. Just cleans up the path. argument is an absolute path.
PACKAGE SETTINGS
Resolve symlinks? Default is 1 ( Not Yet Implemented )
File::PathInfo::RESOLVE_SYMLINKS = 0;
Debug
File::PathInfo::DEBUG = 1;
CAVEATS
This is currently for unix filesystems. File::PathInfo will NOT work on non POSIX operating systems. Trying to set an abs path like C:/something will throw an exception.
The module gets very angry when you set() seomthing like '/etc', anything that sits close to the root of the filesystem. This is on purpose.
TODO
Let people specify a file delimiter for mac and windoze.
Maybe Time::Format is not appropriate here.
BUGS
Please report any bugs to AUTHOR. You can also fill a bug report with http:://rt.cpan.org
PREREQUISITES
Cwd, Carp, Time::Format and possibly Smart::Comments for testing.
SEE ALSO
File::PathInfo::Ext Cwd File::Basename
AUTHOR
Leo Charre leocharre at cpan dot org
COPYRIGHT
Copyright (c) 2009 Leo Charre. All rights reserved.
LICENSE
This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, i.e., under the terms of the "Artistic License" or the "GNU General Public License".
DISCLAIMER
This package 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.
See the "GNU General Public License" for more details.