字节位置:file_get_contents vs fopen

byte position: file_get_contents vs fopen

我需要二进制文件中特定字节范围内的一些数据。
(连接的 jpeg,不要问...)

所以我有来自外部 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 的立场有何不同,有什么想法吗?

你写了

The data chunk is no valid image data

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

fgets — Gets line from file pointer

这意味着 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
}

因此始终使用正确的工具来完成任务,如果您不确定给定 method/function 的作用,总有 not-that-bad documentation 可以一窥。

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

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

这里是 file_get_contents 的文档。