Perl Crash Course: File and Directory Tests and Manipulation

by André Batosti
revision: Vinny alves


Opening Files

To read or write files in Perl, you need to open a filehandle. Filehandles in Perl are yet another kind of identifier.
They act as convenient references (handles, if you will) between your program and the operating system about a particular file. They contain information about how the file was opened and how far along you are in reading (or writing) the file. They also contain user-definable attributes about how the file is to be read or written.

To open a new file on system you need to create the filehandle for this file using the command open

open(filehandle, pathname);

The filehandle is the identifier that will describe the file and the pathname – the full path of the file you trying to open. Typically it is represented by a constant, but when working with complex programs, it is best to use a scalar variable in order to safely pass it from one subroutine or method to another.

Example:

	open(PASS_FILE, "/etc/passwd"); # equivalent to open(PASS_FILE,"< /etc/passwd"); 
	# or
	open(my $pass_file, "/etc/passwd");

Note: it’s always a good idea to test if open() worked well:

	open(PASS_FILE,"/etc/passwd") || die("Can't open passwd: $!n"); # $! gives the system error message

Any modern version of Perl also accepts the 3 parameter notion, which is safer:

	open(PASS_FILE, "<" , "/etc/passwd");

When you done all with the file you need to close then using the command close

        close(PASS_FILE);

Reading Files

You can read from Perl’s filehandles in a couple of different ways. The most common method is to use the file input operator, also called the angle (or diamond) operator (<>). To read a filehandle, simply put the filehandle name inside the angle operator and assign the value to a variable:

	open(MYFILE, "myfile");
	$line = <MYFILE>;

The angle operator in a scalar context reads one line of input from the file. When called after the entire file has been read, the angle operator returns the value undef.

In array context, the whole file is read and stored in the array – one line per element;

Writing Files

To write data into a file you need to open the filehandle to write. The open command before is for reading only. To open for writing we need to use ‘>’ mode to create a new file or overwrite an existing one and ‘>>’ mode to append an existing file or create a new one.

	open(NEWFILE, ">newfile"); # overwrites or creates newfile
	open(MYFILE, ">>myfile"); # appends data to myfile

After open a file to write you can use the print command with the filehandle:

	print NEWFILE "this goes into newfilen"; # note the lack of commas between print and filehandle

More on Modes

So far we’ve seen modes ‘<‘, ‘>’, and ‘>>’. There are other modes we can use depending on our needs. Adding a ‘+’ before ‘>’ or ‘<‘ (making ‘+>’ or ‘+<‘) will grant us read AND write access to the file. ‘+>’, however, will truncate your file first.

Perl also allows you to use pipes on your filenames, print to anonymous temporary files, and much much more.
See perldoc’s open for more details.

Special filehandles

The Perl have some special filehandles that was always open this is for standard input, output and error
They are

  • STDOUT – The standard output
  • STDIN – The standart input
  • STDERR – The error standard output

You can specify which is your default output handle (the one print sends data to when no filehandle is passed) with
the select() function:

	open(FH,"> myfile.txt);
	$old_fh = select(FH); # changes default output and saves original
	print "This goes to myfile.txtn";
	close(FH);
	select($old_fh);
	print "This goes to the screenn";



File test operators

Before you open a file, sometimes it’s nice to know whether the file exists, whether the file is really a directory, or whether opening the file will give a permission denied error. If you could examine the file’s metadata, you could get answers to these questions. For these situations, Perl provides the file test operators. The file test operators all have the following syntax

-X filehandle

OR

-X pathname

The valid operators for file tests are:

  • -r Returns true if the file is readable
  • -w Returns true if the file is writeable
  • -e Returns true if the file exists
  • -z Returns true if the file exists but is empty
  • -s Returns size of the file in bytes if it exists
  • -f Returns true if the file is a regular file rather than a directory
  • -d Returns true if the file is a directory
  • -T Returns true if the file appears to be a text file
  • -B Returns true if the file appears to be a binary file
  • -M Returns the age (in days) since the file was modified

Working with directories

The first step in obtaining directory information from your system is to create a directory handle. A directory handle is something like a filehandle, except that instead of a file’s contents, you read the contents of a directory through the directory handle. To open a directory handle, you use the opendir() function:

        opendir(dirhandle, pathname);

To get the content of the directory you need to use the readdir() function to get the next directory entry or the entire list of files, depending on context (scalar or list, respectively). It returns undef once you reach the end of your list.

	$next_file = readdir(dirhandle);
       # OR
	@files = readdir(dirhandle);

After you finish you need to close the directory using the function closedir()

	closedir(dirhandle);

A shortcut to this process is to use file globbing techniques:

	@all_files = <*>; # gets you the listing of all files in the current directory
	@shell_scripts = glob("*.sh"); # safer

Basic directory operations

If you need to change, create and remove directories you can use the functions chdir(), mkdir and rmdir using this syntax:

	chdir pathname; # to change remote dir
	mkdir pathname; # to create a directory
	rmdir pathname; # to remove the entire directory

Basic file operations

To remove files you need to use the unlink() function and to rename, use rename() 🙂

	unlink list_of_files;
	rename oldname, newname;

The stat Function

If you need to get all information about a file you need to use the stat() function.

It returns an array containing the following:

0 dev     Device number
1 ino     Inode number
2 mode    File's mode (permissions)
3 nlink   Number of links
4 uid     User ID (UID) of the owner
5 gid     Group ID (GID) of the owner
6 rdev    Special file info
7 size    Size of file in bytes
8 atime   Time of last access
9 mtime   Time of last modification
10 ctime  Inode change time
11 blksz  Disk block size
12 blocks Number of blocks in file
        ($dev,  $ino,   $mode,  $nlink, $uid,     $gid,   $rdev, 
         $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat(pathname);

« Subroutines | TOC | Some built-in functions for everyday use »

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.