1

是否有一些 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)。

那么,我能否以某种方式在上面的代码中“流式传输”文件,使用某种数组访问,例如当我调用 isset() 时自动从文件中读取数据的类?:)

4

1 回答 1

6

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

// 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);
    }
}
于 2012-12-08T23:18:02.710 回答