Sunday, March 2, 2008

Reading a Binary File on Ruby

No, it is not as simple as:

contents = IO.read(path_to_binary_file)

Because it does not work well on Windows platforms. You should do:

contents = open(path_to_binary_file, "rb") {|io| io.read }

Obviously, the key is the binary flag. It can not be passed to IO.read.

I learned this because a co-worker had a mysterious problem sending email attachments with rails. I was not able to help her (that IO.read never seemed suspicious to me), but once she found the solution, all became clear.

But you know, the real bug was she using Windows as a development platform, right?.

Update: Changed recipe to use open instead of IO.open. Thanks to Brian Hartin for pointing that in the comments.

4 comments:

Brian Hartin said...

For me, on Windows XP with Ruby 1.8.6, this example won't work because IO's 'open' method won't take a filename; it wants an integer file descriptor. Using Kernel's 'open' works, though, e.g. simply 'open(...) {...}'.

Puzzled in Orient said...

Thanks. This was a big help!

psugar said...

Thanks for posting this. I spent hours trawling the web for this (ruby noob).

Steve Hunter said...

Lifesaver! Thanks again and again for posting this.