Filehandling in a Nutshell


The File System, base of storage but still many people tend to ignore this. Why ?

Simple, cause it's slower than databases. Why ?

Well, I don't know the inner details but I know that memory processing (database) is faster than doing multiple hard disk reads. Anyway this is beyond the scope of what I intend to do here.

Today, not many people use files for storing large amounts of data, when it constantly needs to be read, written to, and simultaneous writes can corrupt the data. But a mechanism called Flock allows locking of a file so that multiple writes are not allowed.

First let's get to the basics of file handling; Procedure :

(1) Reading From File
(2) Writing To File
(3) Appending To File

Reading A File :

<?php
$file_name = "data.dat";
// absolute path : \home\data.dat 

$file_pointer = fopen($file_name, "r");
// "r" is the mode, or the action we're
// going to perform on the file
// Detailed info at end of page 

$file_read = fread($file_pointer, filesize($file_name));
// Reading the file contents, through the pointer 

fclose($file_pointer);
// everything comes to an end! 

print "file contents are $file_read"; 

?> 

Writing To File : 

$file_name = "data.dat";
// absolute path : \home\data.dat 

$file_pointer = fopen($file_name, "w");
// "w" is the mode, or the action we're
// going to perform on the file
// Detailed info at end of page 

fwrite($file_pointer, "what you wanna write");
// Writing to the file, after truncating it
// to 0 bytes 

fclose($file_pointer);
// everything comes to an end! 

print "data written to file successfully"; 

?> 

Appending To File : 

$file_name = "data.dat";
// absolute path : \home\data.dat 

$file_pointer = fopen($file_name, "a");
// "w" is the mode, or the action we're
// going to perform on the file
// Detailed info at end of page 

fwrite($file_pointer, "what you want to append");
// Appending to the file, without truncating it
// to 0 bytes 

fclose($file_pointer);
// everything comes to an end! 

print "data written to file successfully"; 

?>
Now let's come to the tweaking part, the above was an intro so you could be on your feet! Let's go brain dipping in the water!

Some times there can be multiple writing (mostly on high traffic websites) which causes useless values to enter the file, for e.g. :


info.file -> 

|1|Mukul|15|Male|India (\n)
|2|Linus|31|Male|Finland (\n) 

now another person registering clashes with another then ->

info.file -> 

|1|Mukul|15|Male|India
|2|Linus|31|Male|Finland
|3|Rob|27|Male|USA|
Bill|29|Male|USA

In the above case when PHP writes to info.file for Rob, Bill also starts writing and at that instance when '\n' for Rob was still to be written. Causing a file sequence break!

We don't want this happening, do we ? I'll take NO as the answer for the sake of progressing.
So, let's look at file locking :


<?php

$file_name = "data.dat"; 

$file_pointer = fopen($file_name, "r"); 

$lock = flock($file_pointer, LOCK_SH);
// I use 4.0.2 so LOCK_SH or you can use 1. 

if ($lock) { 

 $file_read = fread($file_pointer, filesize($file_name));
 $lock = flock($file_pointer, LOCK_UN);
 // Use 3 if < PHP4.0.2 

} 

fclose($file_pointer); 

print "file contents are $file_read"; 

?gt;
In the above if 2 files read.php and read2.php access the file then both of them will be able to read it, but incase a program needs to write to the file it will have to wait till the read operation finishes and the lock is released.


<?php

$file_name = "data.dat"; 

$file_pointer = fopen($file_name, "w"); 

$lock = flock($file_pointer, LOCK_EX);
// Use 2 if you use < PHP4.0.2 

if ($lock) { 

 fwrite($file_pointer, "what u wanna write");
 flock($file_pointer, LOCK_UN);
 // Use 3 < PHP4.0.2 

} 

fclose($file_pointer); 

print "data written to file successfully"; 

?gt;

Though using "w" is only used for overwriting data and to me can't be put to practical use!

<?php

$file_name = "data.dat"; 

$file_pointer = fopen($file_name, "a"); 

$lock = flock($file_pointer, LOCK_EX);
// Use 2 if you use < PHP4.0.2 

if ($lock) { 

 fseek($file_pointer, 0, SEEK_END);
 // Use this if < PHP4.0RC1 : fseek($file_pointer, filsize($file_name)); 

 fwrite($file_pointer, "what u wanna write");
 flock($file_pointer, LOCK_UN);
 // Use 3 < PHP4.0.2 

} 

fclose($file_pointer); 

print "data written to file successfully"; 

?gt;

Hmmm... something different in appending data, yes FSEEK! It's always good to make sure that the file writing cursor is at the end of the file.

For doing all this in windows, just escape the file names with a '\'.

MISC NOTES ABOUT FLOCK :

Flock() locks the file only after the file has been opened. So incase at instance A the file was opened and at instance A.5 the lock was obtained. Now the file contents are the contents that were present at instance A and not when the other program finished whatever (appending assumed). Hence fseek should always be used not only in appending but also when reading file contents.


MISC ABOUT MODES : 

'r' - Open for reading only; place the file pointer at the beginning of the file. 

'r+' - Open for reading and writing; place the file pointer at the beginning of the file. 

'w' - Open for writing only; place the file pointer at the beginning of the file and truncate
        the file to zero length. If the file does not exist, attempt to create it. 

'w+' - Open for reading and writing; place the file pointer at the beginning of the file and
          truncate the file to zero length. If the file does not exist, attempt to create it. 

'a' - Open for writing only; place the file pointer at the end of the file. If the file does not
       exist, attempt to create it. 

'a+' - Open for reading and writing; place the file pointer at the end of the file. If the file
         does not exist, attempt to create it.


Rate this article