PHP中的随机访问文件

时间:2012-12-08 23:15:18

标签: php file random-access

是否有一些PHP函数或类允许我读取像字符数组这样的文件?

例如:

$string = str_split('blabla');

$i = 0;

switch($string[$i]){

  case 'x':
    do_something();
    $i++;


  case 'y':
    if(isset($string[++$i]))
      do_something_else();
    else
      break;

   case 'z':
      // recursive call of this code etc..

}

我知道我可以使用$string = file_get_contents($file),但问题是我获得了大量内存用于800K的小文件(如80MB)。

所以,我可以通过某种类型的arrayaccess以某种方式“流式传输”上面代码中的文件,当我调用isset()时会自动从文件中读取数据? :)

1 个答案:

答案 0 :(得分:5)

您可以使用fseekfgetc在文件中跳转并一次阅读单个字符。

// Leaves the file handle modified
function get_char($file, $char) {
   fseek($file, $char);
   return fgetc($file);
}

你提到你特别希望数组行为。您可以构建一个实现ArrayAccess的类来支持它。

由于以下几个原因,这可能是危险的:

  • 您需要防范请求索引超过文件长度的$char输入
  • 文件句柄会不断变异(应该没问题,只要你不在其他地方使用它)
  • 这可能效率低下(通过缓存过去的请求来抵消)

稍微更有效的替代方案是“懒惰地”读取文件(即,以块的形式而不是一次性读取它)。这是一些(未经测试的)代码:

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);
    }
}