CMPS 335 Advanced Web Publishing
Perl and CGI Programming
Reading and Writing Data Files
In running a Perl script, we can retrieve (input) data from
or write (output) data to an external file stored on the server.
A data file has a regular file name, but it is referenced in a
script through a label called filehandle. The file handle is
a handy way to refer to the file. The open statement opens a
file and initialize the file handle. You perform all of the file
operations on this handle until the file is closed. File handles are
usually spelled using all uppercase letters to distinguish the filehandle
from Perl's reserved words, which are all lowercase. STDIN is a
predefined filehandle representing a script's normal input, which is the
keyboard by default. STDOUT is a predefined filehandle representing
the screen by default.
The external data file discussed here is called a flat-file
database. Flat-file databases are typically ASCII text files
containing one record of information per line. The line termination
serves as the record delimiter.
CGI scripts can get data from a form and generate data to the
browser. They can also reads data from or write data into a
file. When we run a CGI script, it is run with the
world-executable permissions. In order to write to a data file, we
must make it world-writable.
Opening a File
Before you can read from or write to a file, you have to open the
file with the following file opening statement:
open(FILEHANDLE, "filename");
The filehandle is associated with the filename when the file is
opened. The filename may be prefixed with one of the following open
operators. The default open mode is read-only.
operator operation
-------- -----------------------------------------
< Input (Read)
> Output (starting at the beginning of the
file and overwrite any existing data)
>> Output (write to end of existing file)
Examples:
open(INF,"records.dat");
open(OUTF,">>records.dat");
Because a file opening operation can fail, an error function may be
used with the system error message variable $!. The $!
variable contains the last system error message and is useful
for determining the failure condition as shown in the following
example (counter1.cgi):
:
open(INFILE, "countts.dat") or errorMessage();
:
:
sub errorMessage {
print "File could not be opened: $!");
exit;
}
Locking a File
Several visitors may try to open and write to the same data file
at the same time. To get exclusive access to the file and to
prevent possible file damage, use the following file locking function:
flock(FILEHANDLE, 2);
where 2 is the file locking mode for exclusive lock.
The lock is released when the script finishes running, allowing the next
CGI to access the file. You should also reset the file
pointer using the seek function.
Positioning with the SEEK Function
Normally, when you open a file for reading, the file handle is
positioned at the start of the file. The following seek function
allows the file pointer to be moved forward and backward throughout the file.
seek(FILEHANDLE, offset, whence);
where offset is the number of lines to move the pointer,
relative to whence, which can be one of the three values:
0 beginning of the file
1 current location
2 end of the file
Examples:
seek(INFILE, 0, 0); # Rewind the file to the beginning
seek(INFILE, -10, 2); # The pointer is moved backward
Closing a File
When you are finished reading or wrting a file, close the file using
the close function as shown below:
Files are also automatically closed when the execution of a script ends.
Reading a File
Of the multiple ways to read data from a file, the file input
operator < > is the most straightforward. The input
operator reads the contents of a file in two different ways: reading one
line at a time into a scalar variable or reading the entire file into an
array as shown below:
$scalar = <FILEHANDLE>; # Read one line into a scalar variable
@array = <FILEHANDLE>; # Read the entire file into an array
A more flexible way to read data from a file is to use the read
function to read a fixed amount of data using the following syntax:
read (FILEHANDLE, buffer, length [, offset]);
where buffer is a scalar variable to read the data into,
length is the number of bytes or characters to read, and
offset is the distance from the beginning of the buffer where the
input is to go. The offset is optional. Examples:
read(STDIN, $studentName, 20);
read(INFILE, $buffer, 255);
Writing to a File
The print function can be used to save data to a file or to display
data on screen using the following forms:
print FILEHANDLE "list";
print "list";
print;
The default filehandle is STDOUT, which is to your computer monitor
(screen).
File I/O Examples
Example 1 (standardIO.cgi)
[jhu@cs cgi-bin]$ cat standardIO.cgi
#!/usr/bin/perl
# STDIN and STDOUT are default file handles opened at startup.
# STDIN is normally set to the computer keyboard
# STDOUT is normally set to the computer monitor
print STDOUT "Enter the first number a: ";
$a = ;
print "Enter the second number b: ";
$b = ;
$c = $a + $b;
print "Sum is $c \n";
# End standardIO.cgi
[jhu@cs cgi-bin]$ perl standardIO.cgi
Enter the first number a: 7
Enter the second number b: 5
Sum is 12
Example 2 (counter.cgi)
[jhu@cs cgi-bin]$ cat counter.cgi
#!/usr/bin/perl
open(INFILE, "counts.dat") || &errorMessage;
flock(INFILE,2);
seek(INFILE,0,0);
$count = <INFILE>;
close(INFILE);
$count = $count +1;
open(OUTFILE,">counts.dat");
flock(OUTFILE,2);
seek(OUTFILE,0,0);
print OUTFILE "$count";
close(OUTFILE);
print "Content-type:text/html\n\n";
print " Visitor count: $count.\n\n";
sub errorMessage{
print "Content-type:text/html\n\n";
print "The server can't open the data file.\n";
print "Either the permissions are wrong or the file doesn't exist.\n";
exit;
}
[jhu@cs cgi-bin]$
B. Data File (counts.dat)
Create this file with the initial value 0 on the first and only line
of the file. Make the file world-writable (permissions 666).
[jhu@cs cgi-bin]$ cat counts.dat
10
[jhu@cs cgi-bin]$ chmod 666 counts.dat
C. Running the script counter.cgi in the Unix command shell
[jhu@cs cgi-bin]$ perl counter.cgi
Content-type:text/html
Visitor count: 11.
D. Running the script counter.cgi in the browser's window
(The following output appears in the browser's window)
Visitor count: 12.
E. The Server-Side Include Statement
Add the following SSI statement to the HTML page you want counted
and at wherever the result is to be displayed.
<!--#exec cgi= "cgi-bin/counter.cgi"-->
(Note: The HTML document that contains the SSI should have 755
permissions and the .shtml extension to be server parsed)
Return to CMPS 335 Home Page
Return to Web Site Home Page