While file_get_contents() is convenient for small files, professional applications often require explicit control over the file stream for three main reasons:
- Handling Very Large Files: To avoid crashing the server by loading a massive file into memory all at once.
- Streaming: Reading data in small chunks (e.g., streaming a media file).
- Precise Pointer Control: Moving the read position (the pointer) to a specific byte in the file.
This requires the traditional fopen() structure you encountered earlier, combined with functions that move the pointer.
1. Opening the File Stream (fopen())
The process starts by opening the file and getting a file resource handle (a pointer). We’ll focus on the read modes.
| Function | Purpose |
fopen(filename, mode) | Opens the file and returns a resource pointer or FALSE on failure. |
Example:
<?php
$file = 'data_stream.log';
// Attempt to open the file in 'read-only' mode ('r')
$handle = fopen($file, 'r') or die("ERROR: Could not open the file $file.");
?>
2. Reading Data in Chunks (fread() and fgets())
Once the file is open, you can read it incrementally.
Reading a Specific Number of Bytes (fread())
The fread() function reads a specified number of bytes from the current pointer position.
<?php
$handle = fopen('data.bin', 'r');
// Read the first 1024 bytes (1 kilobyte) of the file
$chunk = fread($handle, 1024);
echo "Read 1KB chunk: " . strlen($chunk) . " bytes.";
// The pointer is now automatically moved 1024 bytes forward.
fclose($handle);
?>
Reading Line by Line (fgets() and fgetc())
fgets(): Reads a single line from the file until it hits a newline character (\n) or the end of the file. This is the most common method for processing text files.fgetc(): Reads a single character from the file.
<?php
$handle = fopen('user_list.txt', 'r');
// Loop until the pointer hits the End-Of-File marker
while (!feof($handle)) {
// Read one line at a time
$line = fgets($handle);
echo "Processing line: " . htmlspecialchars($line) . "<br>";
}
fclose($handle);
?>
3. Pointer Control (fseek())
The fseek() function allows you to move the file pointer to a specific location within the file stream, giving you precise access.
| Function | Purpose |
fseek(handle, offset, whence) | Moves the file pointer to the specified position. |
ftell(handle) | Returns the current position of the file pointer (the offset in bytes). |
| whence Argument | Description |
SEEK_SET | Sets the position relative to the beginning of the file (0 is the start). (Default) |
SEEK_CUR | Sets the position relative to the current pointer position. |
SEEK_END | Sets the position relative to the end of the file. |
Example: Jumping to the Middle of a File
<?php
$handle = fopen('large_data.txt', 'r');
// 1. Get the size of the file
$fileSize = filesize('large_data.txt');
// 2. Jump to the middle of the file (offset is half the size)
$middle_offset = intval($fileSize / 2);
fseek($handle, $middle_offset, SEEK_SET);
echo "Pointer moved to byte: " . ftell($handle) . "<br>";
// 3. Read 50 bytes from the new position
$data_from_middle = fread($handle, 50);
echo "Data read from middle: " . htmlspecialchars($data_from_middle);
fclose($handle);
?>
4. Closing the Stream (fclose())
It is critical to close the file handle when you are finished to release the system resource.
| Function | Purpose |
fclose(handle) | Closes the file pointer/resource. |
<?php
// ... operations here ...
fclose($handle);
?>
