2009-07-28 5 views
10

Próbuję wysłać serię binarnych bajtów przez gniazdo, aby spełnić określony standard, którego używa moja firma. Nikt w mojej firmie nie używał do tego Ruby, ale w innych językach przesyła dane po jednym bajcie na raz (zwykle z jakąś metodą "pack").W jaki sposób Ruby obsługuje bajty/pliki binarne?

Nie mogę znaleźć pliku binarnego w locie ani tworzyć bajtów (najbliżej mogę znaleźć, jak przekształcić ciąg znaków w bajty reprezentujące jego znaki).

Wiem, że można powiedzieć coś w stylu:

@ var = 0b101010101

Ale w jaki sposób przekonwertować ciąg w postaci „101010101” lub otrzymanej liczby całkowitej utworzonej kiedy robię string.to_i (2) do rzeczywistego pliku binarnego. Jeśli po prostu wyślę ciąg przez gniazdo, czy to nie będzie po prostu wysyłać ASCII dla "0" i "1" zamiast literalnych znaków?

Z pewnością istnieje sposób, aby zrobić to natywnie w Ruby?

Odpowiedz

10

Aby ciąg znaków, który ma dowolną sekwencję bajtów, zrób coś takiego:

binary_string = "\xE5\xA5\xBD" 

„\ x” jest specjalnym ucieczka zakodować dowolny bajt z hex, więc " \ xE5 "oznacza bajt 0xE5.

Następnie spróbuj wysłać ten ciąg na gnieździe.

+0

Dlaczego w łańcuchu binarnym jest jakiś znak "/"? – why

+2

Jest całkiem możliwe, że łańcuch binarny ma bajt o wartości 0x2F (47). To jest kodowanie ASCII "/", więc jeśli "sprawdzisz" ciąg Ruby zwykle wypisze "/". To samo dotyczy każdej postaci ASCII. Ruby tak naprawdę nie wie, czy twój ciąg znaków jest "ciągiem binarnym", to że Ruby jest ciągiem bajtów (z wyjątkiem 1.9 dodało trochę informacji o kodowaniu). –

+0

Dzięki! bardzo mi to pomaga – why

9

Spójrz na metodę String.unpack. Oto przykład:

str = "1010" 
str.unpack("cccc") 
=> [49, 48, 49, 48] 

Da ci to wartości całkowite. Istnieje więcej sposobów na konwersję.

+0

Zanim ten post został zredagowany, powiedział mi o Array.pack. Nie bardzo to rozumiem. Jeśli mam: @bob = ["111111111", "1000", "1111"] lub cokolwiek, a następnie mówię: @ bob.unpack (b *), wyświetla coś w stylu: "/ 377" Czy to jest poprawny plik binarny? Czy nie jest to tylko pierwszy element tablicy? Jak mam to zrobić w całej tablicy? – Jenny

+0

Array.pack jest przeciwieństwem String.unpack. W twoim przykładzie bob.pack ('b *') pakuje tylko pierwszy element tablicy. Prawdopodobnie chcesz bob.pack ("b * b * b *"). Jest to jednak coś innego niż to, o co pytasz w pytaniu. – kgiannakakis

14

Nie wiem, czy to pomaga, ale można indeksować bity w liczbie całkowitej w ruby.

n = 0b010101 

n # => 21 

n = 21 

n[0] # => 1 
n[1] # => 0 
n[2] # => 1 
n[3] # => 0 
n[4] # => 1 
n[5] # => 0