Дорогие специалисты, помогите разобраться с чтением бинарных данных! Никогда этого не делала:-). Пишу на PHP, вот не могу найти инструментов подходящих в мануале.Есть база данных, в ней одно поле содержит бинарные данные сложной структуры:
100 строк,
каждая строка начинается с заголовка такой структуры:struct FrequencyData
{
unsigned short frequency;
unsigned short gain_control
unsigned short pulse_time;
unsigned char pulse_length;
unsigned char threshold_x
unsigned char count_o;
};дальше в зависимости от значения count_o идет сколько-то данных еще другой структуры.
То есть, длина каждой строки разная, узнать длину строки можно только прочитав заголовок строки и узнав значение переменной count_o.
======================Я делаю SQL-запрос к базе (SELECT .... ) и читаю эти данные в переменную $mydata, как и с обычными данными (правильно?).
дальше нужно это все преобразовать в нормальные:-) данные, чтобы потом их читали люди.У меня 2 мысли:
1. Сделать чтение по строкам. Но какой функцией?
2. Считать из строки этот самый заголовок, прочитать функцией unpack() и дальше из него определить сколько еще там данных.То есть вопрос. как мне "выкусить" одну строку и потом ее заголовок? Какие есть для этого инструменты в PHP?
http://stackoverflow.com/questions/3993762/php-passing-c-str...
Да и еще, select вернет строку, бинарные данные надо получать c помощью бинарных функций http://us2.php.net/manual/ru/function.pg-lo-read.php.Вообще то странно как с принципе можно записать бинарные данные в строку.
Да все странно:-(. Уже поняла, что для начала нужно узнать, как получить эти бинарные данные из базы корректно? SELECT получается подходит только для обычных данных.> Да и еще, select вернет строку, бинарные данные надо получать c помощью
> бинарных функций http://us2.php.net/manual/ru/function.pg-lo-read.php.
> Вообще то странно как с принципе можно записать бинарные данные в строку.
> Да все странно:-(.
> SELECT получается подходит только для обычных данных.Ну что за бред!
>> Да и еще, select вернет строку, бинарные данные надо получать c помощьюЭто только у пЫхеров которые как известно упоротые :(
>> бинарных функций http://us2.php.net/manual/ru/function.pg-lo-read.php.
>> Вообще то странно как с принципе можно записать бинарные данные в строку.Вообщето правильный вопрос - поле какого типа мы имеем в таблице. А уж от ответа зависит как и что делать. Пыхеры тагыдымскийконьзаногу! :(
М-да...$link = MYSQL_CONNECT($hostname,$username,$password);
if (!$link) { die("Не удается создать соединение с сервером $ERRMSG "); }
@MYSQL_SELECT_DB("$dbName") OR DIE("Не удается создать соединение с базой данных");
$query = ("SELECT profile FROM ... WHERE ... ");
$result = MYSQL_QUERY($query);- старая добрая конструкция возвращает НЕЧТО в переменную
$profile = mysql_result($result,0,"profile");
Дальше я "честно", пытаюсь
$arr = unpack( 'S3/C7/c*', $profile );
чтобы начало прочитать:-).
=============================================
profile - это поле типа mediumblob.
Структура данных описана в первом моем посте.
Это 100 строк, каждая состоит из заголовка такой структуры:
struct FrequencyData
{
unsigned short frequency;
unsigned short gain_control
unsigned short pulse_time;
unsigned char pulse_length;
unsigned char threshold_x
unsigned char count_o;
};
дальше в зависимости от значения count_o идет сколько-то данных еще другой структуры.================================================
А вот эти unsigned short и unsigned char - не будет ли путаницы, если запаковывали данные на С (по-видимому, спрошу в понедельник),
а распаковываем на php.
А то предостерегают в мануале по php, что
"PHP хранит значения как signed. Если распаковать large unsigned long и оно будет иметь тот же размер, что и хранимое PHP значение,
то результатом будет отрицательное число, даже если было указано распаковывать как unsigned. "
(http://www.php.net/manual/ru/function.unpack.php)PS извините за длинность текста...:-)
Как решается проблема "\0" в данных??
В "C" к примеру есть http://dev.mysql.com/doc/refman/5.6/en/mysql-fetch-lengths.html и данные считываются по длине, в PHP такого не нашел, возможно ошибусь но думаю что php с бд общается строками.
Например вот тут http://onlamp.com/pub/a/php/2000/09/15/php_mysql.html?page=1 описан некий способ, с экранированием символов, но если писали в базу на "C" то можно воспользоваться http://dev.mysql.com/doc/refman/5.6/en/mysql-real-query.html и не париться.
Собственно как прочитать N-size данных из поля в PHP я не нашел, и скорее всего в переменой $profile будет все до первого "\0".Собственно но этому и речь зашла про бинарные функции.
Результат.Проблема решилась с помощью 2-х простых вещей:
1. как я писала выше, стандартное соединение с базой Mysql->Connect($host,$database,$user, $password);
и запрос SELECT. В переменную считывается байт в байт то, что в базе.2. unpack($format, $profile);
Никаких дополнительных "бинарных" функций не потребовалось.
"проблема "\0"" также никак не проявилась,возможное потому что данные запаковывали грамотные люди:-).Единственное что - пришлось перейти на perl, потому что php действительно все unsigned char прочитал некорректно. Ccылку на документацию по php, где об этом написано, я привела выше.
Одна та же структура одним и тем же шаблоном "S3 C7"
прочиталась по-разному:PHP::
0 000
1 -4
2 3
3 4
4 0
5 20
6 0
7 100
8 10
9 0PERL:
0 1001
1 4
2 20
3 100
4 10
5 0
6 0
7 0
8 0
9 0А структура такая:
struct FrequencyData
{
unsigned short frequency;
unsigned short gain_control
unsigned short pulse_time;unsigned char pulse_length;
unsigned char band;
unsigned char type;
unsigned char threshold_o
unsigned char threshold_x
unsigned char count_o;
unsigned char count_x;
};Всем ответившим спасибо:-)