Reading from and Writing to Files

Opening Files

You must first open a files before you can either read or write to it, basically it lets the Operating System know that no one else can modifiy the file while you have it open. When you open a file you must supply two arguments

The filevar name (also known as a file handle) can be any sequence of letters, digits and underscores, as long as the first character is a letter, also do not use any keywords.

The file can be opened in one of three modes, the success status is return, true means the files sucessfully opened, false means the file was not opened.

read mode open(MYFILE, "file1");
write mode

open(MYFILE, ">file1");

Note: notice the '>' character before the filename, this means write mode

append mode

open(MYFILE, ">>file1");

Note: notice the '>>' character before the filename, this means append mode

Checking if the file was opened

if ( open(MYFILE, ">file1") ) {
    print "SUCCESS: the file was opened sucessfully";
}

Reading from a file

Once the file has been opened you can now read from it, you enclose the file handle in angle brackets (< and >).

Reading from a file if (open(MYFILE, "file1") {         ## Create a Read-Only file handle
   $line = <MYFILE>;                ## Read in a line
   while (line ne "") {
      print ($line);
      $line = <MYFILE>;             ## Read in a line
   }
}
Read the entire contants of a file into an array

open(MYFILE, "file1") || die("ERROR: unable to open file file1\n");
@input = <MYFILE>;
print (@input);

Note: we use the die function to abort if we cannot open the file

Writing to a file

After the file has been opened in write or append mode you can write to the file.

Writing to a file

## Open the file in Read-Only mode
open(DATAFILE, "file1") || die("ERROR: unable to open file file1\n");

## The file contents will be destroyed
open(WRITEFILE, ">file2") || die("ERROR: unable to open file file2\n");

## The contents will not be destroyed, the data will be appended to the file
open(APPENDFILE, ">>file3") || die("ERROR: unable to open file file2\n");

$line = <DATAFILE>;
while ($line ne "") {
   print WRITEFILE ($line);
   print APPENDFILE ($line);
}

Specifying Read and Write Access

To open a file for both readand write access, specify +> before the filename

Read, Write access example

open(DATAFILE, "+>file1") || die("ERROR: unable to open file file1\n");

Note: this options allows you to overwrite portions of a file, it is mainly used with seek and tell which enable you to skip to the middle of a file

 

Standard Ouput and Standard Error

Both the standard output and error point by default to the display but there is no reason why these can point to file.

redirecting STDOUT and STDERR

open(STDERR, ">c:/perl/error.log") || die("ERROR: unable to open error logfile\n");

open(STDOUT, ">c:/perl/program.log") || die("ERROR: unable to open program logfile\n");

Closing Files

Once you are done with a file you should close it, this lets the Operating System know you are done with it, so that others can use your file.

Close a file close(MYFILE);

File-Test Operators

There are a number of file test-operators, to check the status of a file, to see a full listing check the perl cheat sheet.

File-Test operator example one

if ( -e "file1") {
   open(MYFILE, "file1") || die("ERROR: unabl;e to open file file1");
} else {
   print "ERROR: file does not exists";
}

Note: check that the file exists

File-Test operator example two

if ( (-e "file1") && (-w "file1") ) {
   open(MYFILE, "file1") || die("ERROR: unabl;e to open file file1");
} else {
   print "ERROR: file does not exists or is not writeable ";
}

Note: check that the file exists and is writeable

File-Test operator example three

print "File size: " . (-s "c:/perl/error.log") . " bytes";

Note: obtain the size of a file

File-Test operator example four
if ( -e MYFILE ) { ... }      ## you can even use the file handle name,
                              ## but only when the file has been opened

Reading from a Sequence of Files

There are times when you want to read multiple files, in Perl there is a special operator that do read mutliple files in one go the <> operator. The <> operator reads from the first file until it is exhausted, then reads the next file and so on.

<> operator example

## Reading into an variable
while ($data = <>) {         ## when finished a null string will be passed terminating the loop
   print ($data);
}

## Reading into an array
@array = <>;                 ## you can now process the array as you wish

## The commandline would be as follows
perl_program file1 file2 file3

Note: the code above will read all 3 files that were passed as arguments.

Using Commandline Arguments

Perl enables you to use commandline arguments any way you want by defining a special array variable called @argv. When Perl starts this variable contains a list consisting of the commandline-arguments..

Commandline-argument example

## Perl command to run
perl_prog hello world

## The array @argv will contain the arguments passed
print("@argv");

## Access each argument individually
print ("First argument passed: $argv[0]");
print ("Second argument passed: $argv[1]");
print ("Third argument passed: $argv[2]");

The special operator <> uses the @argv array to get the file names if passed.

Working with the File System

Perl has a number of built-in functions that can manipulate the filesystem

File Input and Output Functions

Opening Pipes

Two commands can be linked using a pipe. The first commands standard output is piped (linked) to the second connads standard input. To do this we need to associate the file with the command by calling open.

Opening pipe example
(output)

open (MESAAGE, "| mail paul.valle@datadisk.co.uk");
print MESSAGE ("Hello how is the website coming along?");
close (MESSAGE);

Note: The call to open establishes a pipe to the command "mail paul.valle@datadisk.co.uk", the file variable MESSAGE is now associated with this pipe. The call to print add the line to the message to be sent. The call to close closes the pipe and the mail program can then send the mail message.

Opening pipe example
(input)
open (CAT, "cat file*|");
$input = <CAT>;                   ## variable input will now have the cat'ed contents of all the files

Redirecting One File to Another

Unix allows you to direct both the standard outfile file and the standard error file to the same output file. You can also perform the same task with Perl

Redirecting example

open (STDOUT, ">file1") || die("ERROR: open STDOUT failed");
open (STDERR, ">&SDOUT") || die ("ERROR: open STDERR failed");

$| = 1;                           ## turn buffering off for STDOUT
select (STDERR);                  ## change the default file to STDERR (normal default file is STDOUT)
$| = 1;                           ## turn buffer off for STDERR

print STDOUT ("Line One\n");
print STDERR ("Line Two\n");

close(STDOUT);
close(STDERR);

Select Function

This allows you to select a new default file, so that calls to print, write and printf write to file variable STDERR, unless a file variable is explicity specified

Select example

select (STDERR);                  ## This becomes the new default file

eof Function

The eof function checks whether the last input file read has been exhausted, eof returns a non-zero value when all the file has been read.

eof example

while ($line = <>) {
   print ($line);
   if (eof) {                       ## the eof returns a non-zero value, thus executing the if statement
      print ("------ END OF FILE CONTENTS -------\n");
   }
}

Note: you can use the eof() function as well, so you could do eof(MYFILE)

Seek and Tell

Perl provides two functions which enable you to skip forward or backward in a file so that you can skip or re-read data.

seek example

seek(MYFILE, 0, 0);           ## skip to beginning of file
seek(MYFILE, 0, 2);           ## skip to the end of the file

seek(MYFILE, 80, 1);          ## skip forward 80 bytes
seek(MYFILE, -80, 1);         ## skip backward 80 bytes

tell example $offset = tell(MYFILE);

System Read and Write Functions

Perl provides two other functions that read an input file and one function that can write to a file, use these functions if you want fast read and write speeds.

read example read (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
read (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar
sysread example sysread (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
sysread (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar
syswrite example syswrite (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
sysread (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar

Reading Characters using getc

Thyis function reads a single character of input from a file, this can be useful for "hot key" applications. These applications process one character at a time, instead one line at a time.

getc example while(1) {
   $char = getc(STDIN);
   last if ($char eq "\\");           ## remember the first \ is escaping the second \
   print ($char);
}

Directory-Manipulation Functions

mkdir create a new directory
chdir set a directory to be the current working directory
opendir In order to list a directory you need to open it first
closedir When you are fisnihed with a directory you close it
readdir when a directory is opened you can now read all the filenames or subdirectories within the directory.
telldir and seekdir You can skip forwards or backwards within a directory structure.
rewinddir You can rewind backwards in a directory
rmdir You can remove a directory, the directory must be empty first.
Examples
mkdir mkdir ("/u01/oracle/data01", 0777);
chdir chdir ("/u01/oracle/data01");
opendir opendir (DIR, "/u01/oracle/data01");
closedir closedir (DIR);
readdir $filename = readdir(DIR);             ## read the first filename of the directory
@files = readdir(DIR);                ## read all the filenames into an array
telldir and seekdir $location_path = tell(DIR);           ## tells where abouts you are in the directory structure

seekdir(DIR, "/u01/oracle/data01");   ## set DIR to the new location
rewinddir rewinddir(DIR);
rmdir rmdir(DIR);                           ## directory must be empty

File-Attribute Functions

You can also use a number of the file test-operators with some of the commands below, to see a full listing check the perl cheat sheet.

rename change the name of a file
unlink and link use unlink to delete a file and use link to create hard links
symlink used to create symbolic links (soft link)
readlink returns the filename to which the file is linked to.
chmod changes access permissions
chown changes the owner of a file
umask sets the default access permissions for a file
truncate reduce a files size to a specified length
stat retrieves information about a particular file
lstat same as stat but presumes that the filename passed is a symbolic link
time to obtain the number of elapsed seconds from Jan 1 1970 to the npresent time, call this function
gmtime and localtime convert the value returned by time to either Greenwich Mean Time or your computers local time
utime set access and modification times of files
fileno return the Inode number of the file
flock and fcntl flock is a file locking function and fcntl provides constants for use with various Perl built-in functions
Examples
rename rename("file1", "file2");                      ## rename file1 to file2
unlink and link

files_deleted = unlink ("file1", "file2");     ## delete the files file1 and file2, returns number of
                                               ## files acutally deleted

link("/u/pvalle/file1", "/u/pvalle/file2");    ## create a hard link

symlink symlink("/u/pvalle/file1", "/u/pvalle/file2"); 
readlink $linkname = readlink("/u/pvalle/file2");       ## $linkname will contain the actaully filename
chmod ## chmod (<perms>, <files>);
chmod (0777, "file1");
chmod (0777, @filelist);
chown # chown (<userid>,<groupid>, <files>);
chown (17, -1, "file1");
chown (17, -1, @filelist);
umask $oldmask = umask(0022);                        ## $oldmask will contain the old mask value
$current_mask = umask();                       ## get the current mask value
truncate truncate ("/u/pvalle/logfile.log", 5000);      ## truncate file to 5000 bytes
stat stat("/u/pvalle/logfile.log");

Note: stat returns a list detailing information on the file
lstat lstat("/u/pvalle/logfile.log");
time $currtime = time();                            ## returned elapsed-seconds value
gmtime and localtime

$timelist = gmtime(time());
print $timelist;

$timelist = localtime(time());
print $timelist;

utime $acctime = -A "file1";
$modtime = -M "file1";
utime( $acctime, $modtime, "file2");           ## set the access & modification times the same as file1
fileno $filedesc = fileno(MYFILE);
flock and fcntl fcntl (<filevar>,<fcntlrtn>,<value>);
flock (<filevar>,<flockop>);

Note: best to see the Unix man pages for fcntl and flock

List-Manipulation Functions

List-Manipulation Functions