2012-12-08 35 views
0

是否有一些PHP函数或类允许我像字符数组一样读取文件?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()时自动从文件读取数据? :)

+0

不,它不是真正的随机。我将只向前移动$ i ... – Alex

回答

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

还有字符编码需要担心。你可以跳到一个多字节glpyh的中间点,这将是非常令人沮丧的线... – Charles

+0

谢谢,我设法做到这一切后,所有与fgetc(我不需要fseek),内存使用情况是正常的,但与file_get_contents相比似乎非常慢,比慢5倍(约1.5秒)慢。这个函数实际上是通过char来读取char文件吗?如果是这样,是不是有类似的功能,像8K的缓冲区中读取文件?我的意思是表现得像fgetc,但更有效地读取文件 – Alex

+0

@Alex如果你想读缓冲区,使用['fread'](http://php.net/fread)并指定你想要的数据长度读。逐字读取将比读取缓冲区慢,然后逐个处理缓冲区,直到读取完所有数据。 – drew010