字节位置:file_get_contents vs fopen

时间:2017-10-13 07:23:25

标签: php file media fopen fseek

我需要二进制文件中范围内特定字节的一些数据 (串联的jpegs,不要问......)

所以我有一个来自外部API的offsetlength数据 (我猜这些是字节位置)

以下内容有效:

$fileData = file_get_contents($binaryFile);
$imageData = substr($fileData, $offset, $length);

但我宁愿不将整个文件加载到内存中,因此尝试fopen

$handle = fopen($binaryFile, 'rb');
fseek($handle, $offset);
$imageData = fgets($handle, $length);

但这并不奏效。数据块不是有效的图像数据 所以我认为我的位置错误fopen

关于substrfopen的排名有何不同的任何想法?

2 个答案:

答案 0 :(得分:4)

你写了

  

数据块无效图像数据

"图像数据" - 但在您的代码中,您调用fgets()来读取该数据。这是错误的,因为图像是二进制数据,而不是文本文件,因此您不希望它按行(docs)读取它:

  

fgets - 从文件指针

获取

这意味着fgets()一旦找到它认为的行结束标记就会停止从文件读取,这通常意味着提前停止并且读取少于$length,因为这样的字节非常低的可能性不是二进制序列。

所以使用fgets()错误的方法,这是主要问题。相反,你应该选择不那么聪明的fread()(它不知道线条和东西,只读你所说的)。最后,当你完成时,你应该fclose()手柄。当然,您应该始终检查错误,从fopen()开始:

if ($handle = fopen($binaryFile, 'rb')) {
    if (fseek($handle, $offset) === 0) {
       $imageData = fread($handle, $length);
       if ($imageData === false) {
          // error handling - failed to read the data
       }
    } else {
        // error handling - seek failed
    }
    fclose($handle);
} else {
   // error handling - can't open file
}

所以总是使用正确的工具来完成任务,如果你不确定给定的方法/功能是什么,那么总是not-that-bad documentation要偷看。

答案 1 :(得分:2)

您也可以使用file_get_contents。看到这条简单的路线:

imageData = file_get_contents($binaryFile, null, null, 0, $length);

这里是file_get_contents的文档。