позиция байта: file_get_contents против fopen

Мне нужны данные из определенного байта в диапазоне в двоичном файле.
(сцепленные JPEG, не спрашивайте …)

Итак, у меня есть offset а также length данные из внешнего API.
(Я бы предположил, что это байтовые позиции)

Что работает, это следующее:

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

Но я бы предпочел не загружать полный файл в память и поэтому попытался fopen:

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

Но это не работает. Блок данных не является действительными данными изображения.
Итак, я полагаю, что я ошибся с позицией fopen,

Любые идеи о том, как позиции отличаются substr против fopen?

5

Решение

Вы написали

Блок данных не является действительными данными изображения

«данные изображения» — но в вашем коде вы называете fgets() читать эти данные. Это неправильно, поскольку изображение — это двоичные данные, а не текстовый файл, поэтому вы не хотите, чтобы оно читалось по строкам (документы):

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
}

Поэтому всегда используйте правильный инструмент для задачи, и если вы не уверены, что делает данный метод / функция, всегда есть неплохая документация заглянуть.

4

Другие решения

Ты можешь использовать file_get_contents, тоже. Посмотрите на эту простую строку:

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

А вот документация file_get_contents.

2

По вопросам рекламы [email protected]