Newbie question - how to write out specific bytes to an IO stream?

C

Collin VanDyck

Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?
 
T

Todd Benson

Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?

String objects are arrays of bytes, so you could simply do...

num_string = "99 111 108 108 105 110"
byte_string = num_string.split.map! {|word| word.to_i.chr}.join

# Now, to illustrate...

byte_string.class
# gives String

byte[0]
# gives 99, the base 10 representation of 1100011
# note that each byte can store numbers up to 255

puts byte_string
# gives collin

If you want to store the 1's and 0's as a text string, you can use the
Integer#to_s(2) method.

hth,
Todd
 
Y

yermej

Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?

I *think* you'll want to use Array#pack. E.g., to write them out in
big-endian order:
a = [99, 111, 108, 108, 105, 110].pack 'n*'
=> "\000c\000o\000l\000l\000i\000n"
file.write a

If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
'n*'. See http://ruby-doc.org/core/ and check Array#pack for more
details on the directives.
 
T

Todd Benson

Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?

I *think* you'll want to use Array#pack. E.g., to write them out in
big-endian order:
a = [99, 111, 108, 108, 105, 110].pack 'n*'
=> "\000c\000o\000l\000l\000i\000n"
file.write a

If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
'n*'. See http://ruby-doc.org/core/ and check Array#pack for more
details on the directives.

Hmm, I was thinking about #pack, but your example creates 12 bytes.
 
C

Collin VanDyck

Thank you for your replies!

Both methods seem to work equally well, but I'm seeming to favor the
pack method because i can just push in my random bytes (0-255) into an
array. I decided to use pack "C*" though, because I think that the C*
directive will limit the packed members to 8 bits, if I'm not mistaken.
 
T

Todd Benson

Thank you for your replies!

Both methods seem to work equally well, but I'm seeming to favor the
pack method because i can just push in my random bytes (0-255) into an
array. I decided to use pack "C*" though, because I think that the C*
directive will limit the packed members to 8 bits, if I'm not mistaken.

Good choice!

Todd
 
A

Alex Young

Todd said:
Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?
I *think* you'll want to use Array#pack. E.g., to write them out in
big-endian order:
a = [99, 111, 108, 108, 105, 110].pack 'n*'
=> "\000c\000o\000l\000l\000i\000n"
file.write a
If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
'n*'. See http://ruby-doc.org/core/ and check Array#pack for more
details on the directives.

Hmm, I was thinking about #pack, but your example creates 12 bytes.
That's because n isn't the code for a byte - you want c or C, for signed
or unsigned char:

irb(main):004:0> a = [1, 2, 3, 4, 5, 6].pack 'C*'
=> "\001\002\003\004\005\006"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,270
Messages
2,571,350
Members
48,036
Latest member
nickwillsonn

Latest Threads

Top