LINUX.ORG.RU

[php] Парсинг бинарного файла

 


0

0

Добрый день!

Есть задачка: в переменной лежит бинарный файл. Его нужно распарсить. Делать это хочется как побайтово, так и строчно.

В голову приходит брать substr нужной длины и с ним работать.

Файл парсится в 1 проход. Средний размер файла = 50кб. Максимальный = 2мб.

Вопрос: на сколько это будет быстро делаться (не в цифрах, а субъективно «медленно» / «нормально»).

Нет ли в php чего-то вроде byte ptr?

Есть ли смысл под это дело запускать отдельный C'шный бинарник / perl-скрипт? Как лучше запускать: из php или cron'а?

И ещё, php воспринимает строку как массив байт или слов(два байта)? Байты

★★★★★

Последнее исправление: helios (всего исправлений: 2)

> В голову приходит брать substr нужной длины и с ним работать.

Попробуйте ещё получить доступ к переменной как к массиву.
$binary_var[$some_index]

Но IMHO лучше заюзать pack/unpack: http://www.php.net/manual/en/function.unpack.php

Вопрос: на сколько это будет быстро делаться (не в цифрах, а субъективно «медленно» / «нормально»).

ХЗ. substr() юзать - наверное, медленее, чем через доступ как к массиву... да и я не знаю, спотыкнётся ли сфбстр на нулях '\0' или нет...

Нет ли в php чего-то вроде byte ptr?

нет, нету. Есть ссылки, но ссылки больше ближе к ссылкам в понятии Java, указателей в понятии Си нету.

Есть ли смысл под это дело запускать отдельный C'шный бинарник / perl-скрипт? Как лучше запускать: из php или cron'а?


Если задача разовая и «под себя» (для работы на «своём» железе), то я делал бы отдельный парсер на чём угодно и как угодно. В том числе и попробовав функцию unpack и/или доступ к переменной как к массиву.

Если же планируется отдать потом труды заказчику, то я делал бы только средствами php - неизвестно, какой там хостинг найдёт заказчик и какие функции PHP будут разрешены в safe mode (и будет ли вообще этот safe mode врублен).


Slavaz ★★★★★
()
Ответ на: комментарий от Slavaz

вариант с индексом массива, если мне не изменяет память, будет самым медленным. да и substr парсить бинарные данные помоему глупо, нужно юзать unpack.

trashymichael ★★★
()
Ответ на: комментарий от Slavaz

> Попробуйте ещё получить доступ к переменной как к массиву.

$binary_var[$some_index]


Этот вариант работает. И если бы я писал на asm/C - то так бы и делал. В php же элементы массивф, вроде, не *(A+idx), так что вопрос быстродействия опять возникает.


Задача не «для себя», а скорее для массового использования => буду делать всё на php.

pack/unpack подходит для данной задачки. Сейчас его попробую.

helios ★★★★★
() автор топика
Ответ на: комментарий от helios

Хотя, не с pack/unpack извращаться придётися: я иногда получаю размер следующего блока в предыдущем.

Наверное, тогда лучше всё же индексы юзать (+slice для строкового представления)

helios ★★★★★
() автор топика

что за данные-то? А то может сериализатор-десериализатор какой-нить готовый прикрутить и всё.

true_admin ★★★★★
()
Ответ на: комментарий от trashymichael

на сколько я помню, в unpack нужно вбить шаблон, по которому и разобъют входные данные. А у меня шаблон не постоянный (о длине следующего блкоа я узнаю в предыдущем)

helios ★★★★★
() автор топика
Ответ на: комментарий от helios

Может читать блочно с помощью fread (размер первого блока ведь мы знаем?):
1. прочитали блок
2. unpack
3. узнали размер следующего
4. на шаг 1.

RR
()
Ответ на: комментарий от helios

>> в переменной лежит бинарный файл каюсь, пропустил.

RR
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.