Bug #17673
closedsysseek(0) and '1A' in header return "EOFError (end of file reached)"
Description
The first byte of my file starts with the value '1A' .
Then:
descriptor = IO.sysopen(filePath)
file2Read = IO.new(descriptor)
file2Read.sysseek(0)
p file2Read.sysread(2).unpack('H*')
#=> "EOFError (end of file reached)"
But when I change the first byte of my file to 'AA' for example.
Then:
#=> "aa45"
Is it a bug or am I missing something? I thought sysseek only changed the cursor and nothing else.
This error only occurs with byte '1A' I did the test with the rest of the bytes [00..FF] and there is no problem except with '1A' .
Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
- Status changed from Open to Feedback
I tried your example and was unable to reproduce your problem:
filePath = 'test.txt'
File.binwrite(filePath, "\x1A\x45")
descriptor = IO.sysopen(filePath)
file2Read = IO.new(descriptor)
file2Read.sysseek(0)
p file2Read.sysread(2).unpack('H*')
# => ["1a45"]
Can you try on a different machine to check if this is a local problem?
Updated by stiuna (Juan Gregorio) over 3 years ago
Can you try on a different machine to check if this is a local problem?
Unfortunately I don't have another computer to test the bug with, what version of ruby do you use?
Updated by stiuna (Juan Gregorio) over 3 years ago
Aaah! I don't know if it matters but I use Windows, did you run it on Linux all of a sudden?
Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
- Status changed from Feedback to Closed
I tried on Windows and I was able to reproduce the issue:
C:\Users\jeremye>c:\Ruby30-x64\bin\ruby
filePath = 'test.txt'
File.binwrite(filePath, "\x1A\x45")
descriptor = IO.sysopen(filePath)
file2Read = IO.new(descriptor)
file2Read.sysseek(0)
p file2Read.sysread(2).unpack('H*')
__END__
-:7:in `sysread': end of file reached (EOFError)
from -:7:in `<main>'
From some brief research, this is expected behavior on Windows for text files. You need to put the file in binary mode (IO#binmode):
:\Users\jeremye>c:\Ruby30-x64\bin\ruby
filePath = 'test.txt'
File.binwrite(filePath, "\x1A\x45")
descriptor = IO.sysopen(filePath)
file2Read = IO.new(descriptor)
file2Read.binmode
file2Read.sysseek(0)
p file2Read.sysread(2).unpack('H*')
__END__
["1a45"]
Updated by stiuna (Juan Gregorio) over 3 years ago
Right, that solved it, the Ruby documentation should specify that. Ok, thanks.
Updated by nobu (Nobuyoshi Nakada) over 3 years ago
This is not specific to Ruby, but the very (in)famous text mode spec of Windows (and other dosish systems).