You can use fseek
and fgetc
to jump around in a file and read single characters at a time.
// Leaves the file handle modified
function get_char($file, $char) {
fseek($file, $char);
return fgetc($file);
}
You mentioned you wanted array behavior specifically. You can build a class which implements ArrayAccess
to support this.
This could be dangerous for several reasons:
- You'll need to guard against
$char
inputs that request indices past the length of the file - The file handle will be constantly mutated (should be okay, as long as you're not using it elsewhere)
- This could be inefficient (offset by caching past requests)
A slightly more efficient alternative would be to "lazily" read the file (i.e., read it in chunks rather than all at once). Here's some (untested) code:
class BufferedReader {
// The size of a chunk in bytes
const BUFFER_SIZE = 512;
protected $file;
protected $data;
function __construct($fname) {
$this->file = fopen($fname, 'r');
}
function read_buffer() {
$this->data .= fread($this->file, self::BUFFER_SIZE);
}
function get_char($char) {
while ( $char >= strlen($this->data) && !feof($this->file) ) {
$this->read_buffer();
}
if ( $char >= strlen($this->data) ) {
return FALSE;
}
return substr($this->data, $char, 1);
}
}