pjd pjd - 1 year ago 60
Ruby Question

Unable to upload PDF using Ruby and Windows 7 (no issues using Linux)

I am trying to use Ruby to upload a PDF. My code works fine on my Linux machine, but not on the Windows 7 box I am now trying to use. I am using Ruby 2.2.0 in Windows vs 2.3.0 in Linux.

If I type the following into IRB, my results are very different on Windows vs Linux:

require 'stringio'

fname = 'C:\Sites\Programming\watir-webdriver\websign_tests\eStore.pdf'
# vs on Linux fname = '/home/me/Programming/watir-webdriver/websign_tests/eStore.pdf'
# forward slashes and backslashes give the same end result on Windows

File.readable?(fname) # => true in Windows and Linux

f_obj = File.open(fname)

f_data = StringIO.new(f_obj.read)
f_data.size # => 416 in Windows vs 186550 on Linux

#There is much less output for the following statement in Windows
#than there is in Linux
File.foreach(f_obj) {|x| print "GOT ", x }

GOT %PDF-1.4
GOT %JetForm PDF Support Version 2.3.000
GOT %EncodingObject=0
GOT %√ⁿ²■
GOT 1 0 obj
GOT <<
GOT /Type /Catalog
GOT /Pages 3 0 R
GOT /Outlines 4 0 R
GOT >>
GOT endobj
GOT 5 0 obj
GOT <<
GOT /Length 0000038826 /Filter/FlateDecode/Length1 0000057578 >>
GOT stream
GOT x┌î| |SU÷ =≈¡y/╦╦₧4]ƪI)à╢P
GOT ¶½}╩Zö]û"Ñe)P♦);╚«`í T
GOT éêRE♦§ñÇB┴♣T\G♣ù↓up♦↔╘Y∞ê♫:ÄÆ⌠⌂εK[`µ≈√}■I≤÷Σ¥{╓∩9≈╝↕ äÿ╔J┬◄}╚ê▄«╒τ∩|
GOT Å╝ïƒQôfN¿₧8ΩïrB â►±²I♂µ♣∩z╝d.!╥eB°ëS¬º╬¼ε╡⌠Sⁿü1╕⌂rΩî┼Sε¢₧qà►╗ÅÉ¥╒╙*'L~íΣ⌐┴ä∟
Xï┐╫}=> nil

I have confirmed that the PDF file size is 186,550 bytes on the Windows machine, and it opens normally with Adobe Reader.

I'm not sure why I cannot accomplish this task using Ruby and Windows 7. Am I doing something wrong, or is this a Ruby/Windows bug?

If it's a bug, is there another way to accomplish this task?

Answer Source

A PDF is a binary file, so you need to tell File.open to use binary mode.

This is mostly specific to Windows, as it will otherwise be treating files as text files, whereas on Linux the binary modifier is not needed (it is simply ignored).

So this is what you need:

f_obj = File.open(fname, "rb")

You can read more about the binary flag here: