Navigating within Files - Page 5
August 19, 2002
In Part 1, we looked at opening a file, and reading it either
line by line, or character by character. In this section, we look
at moving around to any position in the file.
When you open a file, PHP keeps track of something called the file
pointer. Normally (unless opening in append mode), this points to
the beginning of the file 9 which is 0). When you read a file with
the fgetc() function, the file pointer is incremented by
one. We can see this in action by using the ftell()
function, which returns the position in the file.
int ftell (int fp)
In Part 1, we've already seen the feof() function, which
returns true if the file pointer is at the end of the file. The
following script take a single line text file, and displays the
movement of the file pointer. Let's assume that the file
potofgold.txt contains a single line containing the
characters - 123456789 and a newline at the end:
<?
$filename = "potofgold.txt";
if (!($fp = fopen ($filename, "r"))) {
print "Error - could not open the file $filename<br>";
}
else {
while (!feof ($fp)) {
$file_pointer = ftell($fp);
print "File pointer: $file_pointer<br>";
$file_char = fgetc($fp);
// do something with $file_char...
}
fclose ($fp);
}
?>
The results would be displayed as follows:
File pointer: 0
File pointer: 1
File pointer: 2
File pointer: 3
File pointer: 4
File pointer: 5
File pointer: 6
File pointer: 7
File pointer: 8
File pointer: 9
File pointer: 10
The file pointer starts at 0, then moves up through characters
1-9, finally moving to 10 after the newline character, which is
also counted as a valid character.
The real power comes from being able to manipulate the file
pointer directly. The rewind() function returns the file
pointer to the beginning of the file, while the fseek()
function allows you to move the pointer to any location in the file.
The rewind() function just take the file handle as an argument:
int rewind (int fp)
The fseek() function takes a file handle, an offset
(how much to move the file pointer), and optionally, an argument
indicating where to take the offset from:
int fseek (int fp, int offset [, option])
Option can be one of SEEK_SET (the default, which sets the offset from the start of the file), SEEK_CUR (sets the offset from the current position of the file pointer), and SEEK_END (sets the offset from the end of the file). The offset can be a positive or a negative number (for counting backwards, especially from the end of the file). The following script demonstrates some of these features
<?
$filename = "potofgold.txt";
if (!($fp = fopen ($filename, "r"))) {
print "Error - could not open the file $filename<br>";
}
else {
while (!feof ($fp)) {
$file_pointer = ftell($fp);
print "File pointer: $file_pointer<br>";
$file_char = fgetc($fp);
// do something with $file_char...
}
rewind($fp);
$file_pointer = ftell($fp);
print "File pointer after rewind: $file_pointer<br>";
fseek($fp,3);
$file_pointer = ftell($fp);
print "File pointer after fseek(\$fp,3): $file_pointer<br>";
fseek($fp,1,SEEK_CUR);
$file_pointer = ftell($fp);
print "File pointer after fseek(\$fp,1,SEEK_CUR): $file_pointer<br>";
fseek($fp,-1,SEEK_END);
$file_pointer = ftell($fp);
print "File pointer after fseek(\$fp,-1,SEEK_END): $file_pointer<br>";
fclose ($fp);
}
?>
This displays:
File pointer: 0
File pointer: 1
File pointer: 2
File pointer: 3
File pointer: 4
File pointer: 5
File pointer: 6
File pointer: 7
File pointer: 8
File pointer: 9
File pointer: 10
File pointer after rewind: 0
File pointer after fseek($fp,3): 3
File pointer after fseek($fp,1,SEEK_CUR): 4
File pointer after fseek($fp,-1,SEEK_END): 9
A warning though - it's easy to make a the common mistake of
getting stuck in an endless loop. For example, by putting the
rewind inside the while loop, feof() will never return a true
value, and the while loop will never end. Don't run this script
below!
<?
// WARNING - don't run this - causes an endless loop!
$filename = "potofgold.txt";
if (!($fp = fopen ($filename, "r"))) {
print "Error - could not open the file $filename";
}
else {
while (!feof ($fp)) {
$file_pointer = ftell($fp);
print "File pointer: $file_pointer ";
$file_char = fgetc($fp);
// do something with $file_char...
// WARNING - don't run this - causes an endless loop!
rewind($fp);
}
fclose ($fp);
}
?>
Handling files with PHP4 - Part 2 - Page 4
Handling files with PHP4 - Part1
Working with directories - Page 6
|