【问题标题】:Consuming variable lengths of data from a fixed length buffer in PHP在 PHP 中使用固定长度缓冲区中的可变长度数据
【发布时间】:2015-11-16 18:27:50
【问题描述】:

我有一个文件太大,我无法一次将其读入字符串,但必须使用缓冲:

$fp = @fopen("bigfile", 'rb');
while (!feof($fp)) {
    //process buffer
}

为简单起见,假设文件包含一系列整数字符串对,其中整数保存字符串的长度。然后我想在process buffer 中实现的代码,是unpack 一个int,从缓冲区中读取那么多字符,然后重复。

对于处理字符串跨越一个缓冲区到下一个缓冲区的情况,我很感激任何建议。我确信这个问题一定已经解决了,并且有一个设计模式,我只是不知道从哪里开始。

任何帮助将不胜感激。

【问题讨论】:

  • 检测何时有跨度,将“开始块”从您读取的最后一个块的末尾剥离,并将您从文件中读取的 var 与该块“填充”。例如while($chunk .= fread(...)) { ...do stuff... if (have partial) { $chunk = get_last_partial(); } else { $chunk = ''; } } 这样你只需将下一个块附加到前一个块的左边,消除分裂。

标签: php buffering file-read


【解决方案1】:

不确定您是否正在寻找更聪明的解决方案,但直截了当:

while (!feof($fp)) {
    $len = fread($fp, 2); // integer-2 bytes ...?
    // <--- add checks here  len($len)==2 and so on...
    $len = unpack('S', $len); // pick the correct format character from http://docs.php.net/function.pack

    while(!feof($fp) && $len) {
        $cbRead = $len < MAX_CHUNK_LEN ? $len : MAX_CHUNK_LEN;
        $buf = fread($fp, $cbRead);
        // <--- add checks here  len($buf)==$cbRead and so on...
        $len -= $cbRead;
        // ... process buf 
    }
    if ( $len!=0 ) {
        errorHandler();
    }
    else {
        processEndOfString();
    }
}

【讨论】:

  • 绝对完美,非常优雅的解决方案,谢谢。解决方案的关键是 while 循环的嵌套,这是我没有想到的。 - 一个小点意味着你的示例代码将无法工作是 unpack 的返回类型是一个数组,所以你需要像 $len = $len[1] 这样的行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多