LINUX.ORG.RU

[Erlang] [Binaries] проблемы и непонимание :)

 


0

0

Всем привет.

есть такой вопрос... чем будут отличатся данные
попавшие в переменную в этих двух случаях:

допустим вычитываем из файла 8 байт данных:

{ok, File} = file:open ("file.bin", [read, raw, binary]).
{ok, Data} = file:read (File, 8).

потом я хочу "отрезать" 4 байта в одну переменную, и 4 в другую:

<<Data_1:4/binary, Data_2:4/binary>> = Data.

и второй вариант

<<Data_1:32/integer, Data_2:32/integer>> = Data.

чем отличаются кординально эти два варианта?

я бы и не стал спрашивать... просто маленький
примерчик разбора mp3 заголовка работает в первом случае, и не
работает во втором :(

ошибка, которую пишет во втором случае:

** exception error: no match of right hand side value 
                    {<<73,68,51,3,0,0,0,0,9,109,84,73,84,50,0,0,0,8,0,0,0,78,
                       97,114,97,121,97,110,...>>,
                     <<"a\245\247">>}

строчка вообще такая
{_, <<D:4/binary, _/binary>>} = split_binary (Data, N),

а если делать так
{_, <<D:32, _>>} = split_binary (Data, N),

то нишиша не работает :(


Думается мне, что тут какое-то фундаментальное непонимание с моей стороны. 
Знающие люди, подскажите, а? :)

Зарание всем спасибо!

Кардинально отличаются следующим:

21> <<D:4/binary,D1:4/binary>> = <<1,2,3,4,5,6,7,8>>.    
<<1,2,3,4,5,6,7,8>>
22> D.
<<1,2,3,4>>
23> D1.
<<5,6,7,8>>

и

16> <<D:32/integer,D1:32/integer>> = <<1,2,3,4,5,6,7,8>>.
<<1,2,3,4,5,6,7,8>>
17> D.
16909060
18> D1.
84281096

По поводу второго вопроса, вместо:

{_, <<D:32, _>>} = split_binary (Data, N),

следует писать так:

{_, <<D:32,_/binary>>} = split_binary (Data, N),

потому как по умолчанию тип _ берётся integer, соответственно не мэтчится.

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

>> {_, <<D:32,_/binary>>} = split_binary (Data, N),

>> потому как по умолчанию тип _ берётся integer, соответственно не мэтчится.

пробовал и так, не работает :(

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

Хм.. У меня R12B-3

Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.6.3  (abort with ^G)
1> f(D).
ok
2> <<D:32,_/binary>> = <<1,2,3,4,5,6,7,8,4,6,7,8,9,10,11,12,13,14>>.
<<1,2,3,4,5,6,7,8,4,6,7,8,9,10,11,12,13,14>>
3> D.
16909060
4> 

anonymous
()
Ответ на: комментарий от Cy6erBr4in

Попробуй вобщем явно тип для D указать, <<D:32/integer,_/binary>>. И не забывай чистить биндинги для переменных в консоле, f(D).

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

Ох, спасибо тебе анонимный товарисч  :))

разницу всю осознал... 

<<D:32,_/binary>>

и правда будет работать, просто чуть дальше у меня есть матчинг:

decode_header (<<2#11111111111:11,
                Vers:2, 
                L_r:2,
                _ProtBit:1,
                BitR:4,
                Freq:2,
                _PadBit:1,
                _PrivBit:1,
                ChanMode:2,
                _ModExt:2,
                _Copy:1,
                _Orig:1,
                _Emphasis:2>>) ->

который действительно не сработает, ведь D у нас будет уже integer,
и я бы понял это раньше, если бы ошибка показывала более точную информацию :)

Спасибо тебе огромное, теперь я всё понял =))

Тему можно считать закрытой.

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