|
|
Reading and Writing to Files on the Server
You are here: irt.org | Articles | CGI & Perl | Reading and Writing to Files on the Server Published on: Sunday 9th August 1998 By: Jason Nugent IntroductionIn the past few articles, we have taken a look at how data is sent to the server, how it is read into your CGI script, and also how to extract that information from its encoded form. Once we had this data, we showed it back to the user to prove to ourselves that the process worked correctly. The problem is, however, is that once the CGI script is done executing, our data is lost. Gone. No more. The next time our script was run, it would start off fresh, with no recollection of what had just happened. Its time to change how this works, it would appear. This article will discuss the mechanisms most often used in Perl scripts to store data out to the filesystem so it can be used again at a later time. Once your data is in a file on the server, other programs may access it, you can manipulate it, graph it, or do just about anything you want with it. I'm going to assume that you are familiar with the decoding process discussed in the other article. I will assume that you have the data stored in an series of variables, ready to be saved out to the filesystem. Let us begin. File HandlesIn order to save or read information from a file (or from STDIN, the location where the information comes into your script when POST is used to submit it), you need a filehandle open. A filehandle is basically a pipeline or gateway to a resource outside the script. Typically, these resources are files located on the server. A filehandle is created when you open a file either for reading, writing, or appending. Printing to or reading from the filehandle represents printing to or reading from the file on the server. To create a filehandle, you need to use the open() command. The structure of the open command is simple, but you can alter the way a file is opened using several modifiers. The basic command is
The FILEHANDLE is the filehandle that is created during the open process. It is through this filehandle that you will be doing all your communicating with the file you have just opened. The "filename" represents the name of the file you wish to open. The filename can contain complete path information as well:
In this example, the entire directory path is entered as part of the filename. The complete path is not necessary for the open() command to work, but I recommend it. It ensures that the file is being created (or read from) the proper directory and allows you to reference files that might not exist in the directory in which the script is being run. You may also store your filename in a variable, and then pass the variable to the open() command as an argument.
Before I discuss the different ways to open the file, I should point out the section of code after the open() command. The statement
will terminate your Perl CGI script if the open command is not successful. There is a good reason for this. If the script is not terminated, it will continue to execute and may cause damage to resources the script has access to. The $! variable contains the error message that is generated by the Perl script if it dies. This message will get added to the standard error message in your web server's error log files which will help you figure out what went wrong. As I mentioned, there are several ways to modify the behavior of the opened file. These involve adding something to the front of the filename. The ones I most typically use are, in no particular order
Locking a FileBecause we are working with CGI programs, you must also consider the fact that many copies of your script may be running all at once, each trying to get a hold of your text file for either reading, writing, or updating. Imagine this scenario - a copy of your script opens your text file. During the time that the script is working, a second copy of your script opens the file, makes some changes and then saves the file out to disk again. When the first copy finishes, it will overwrite the changes made by the second copy of your script. To prevent this from happening, you must lock your file while it is open. Locking a file ensures that no other script may tamper with its contents (or even read the file, if it is locked exclusively) while it is locked. To lock a file, use the flock() command. The flock() command takes two parameters - the type of locking you wish to do, and the FILEHANDLE you wish to lock. The two versions most commonly used in CGI scripts are
and
I should point out that any locked files are unlocked when the perl script closes the file or finishes executing. However, if you are done using a file and still have quite a bit of processing to do, unlock the file. This way, other instances of your script may have access to it. Reading in the File ContentsSo, now we have our script opened, and locked so other scripts cannot access it until we are finished. To read a file into memory (i.e., store it in a variable), we shall make use of the "double diamond" operator, <>. The double diamond operator will read in the complete contents of a FILEHANDLE. In our case, we might want to try something like this.
which will read in the contents of the FILEHANDLE we opened with open(), and store each line in a separate cell in our array @my_file. So, the first line of our file could be referenced using $my_file[0], the second as $my_file[1], etc. When there is no more information to read, <> will return EOF and the process will stop. So, where are we now? Well, we can open a file, lock it, and read its contents. The following snippet of code illustrates the point:
The preceding section of code will read in a file. If we wanted to write to a file, we could do the following:
At this point, there should be a file called "myfile.txt" inside the /home/wwwroot/ directory with the two lines printed to it above. Notice that the print command redirects the output to FILE. By placing the filehandle in the print statement in this manner, you may shuffle information throughout your filesystem. I should point out that your perl script must be able to write in the directory that you want to create the file in. Since most webservers run as user "nobody", your perl script must have the correct permissions to write in that particular directory. This usually means creating a directory with universal write access, so be sure to create this directory in a location not normally accessible by regular users (i.e., outside the webserver document path). You might also want to think twice about doing this on a server with many regular shell accounts. Each person who can log in to the server can potentially overwrite this file. So, with this we can take data that might have been sent to our script via a form on a web page and save it out to a file on the server. If, for example, you have a guestbook form on your page you can open a text file on the server using ">>" and append the new information to the bottom of it. You might have a second script that reads this file and displays the contents of it inside a web page. This is the basic concept behind guestbooks on the web. Working ExampleThe following script will take some basic information about a user and save it out to a file on the server. It will also display the PREVIOUS contents of the file to the user once the script is finished running. The next time a user runs the script, he or she will see the information submitted the first time they ran it. The code is commented, so read it to get an explanation of the internals.
Now that you've read and understood the code you can try it our for yourself: readwrt.htm Feedback on 'Reading and Writing to Files on the Server'
View the profile on Jason Nugent and the list of other Articles by Jason Nugent. |
-- div -->
|