views:

44

answers:

2

I have this:

require 'tempfile'
t = Tempfile.new('test-data')
t.open
t.sync = true
t << "apples"
t.puts "bananas"
puts "contents are [#{t.read}] (#{t.size} bytes)"
t.close

This prints:

contents are [] (14 bytes)

Why aren't the contents actually shown? I'm on Ruby 1.9.2.

+1  A: 

You are probably at the end of the stream, where there are no more bytes left. After writing and before reading you should rewind the file (reopen or seek to position 0).

require 'tempfile'
t = Tempfile.new('test-data')
t.open
t.sync = true
t << "apples"
t.puts "bananas"
t.seek 0
puts "contents are [#{t.read}] (#{t.size} bytes)"
t.close
SztupY
Durrr. Yes, adding a `#close` and `#open` fixed things. Is this the idiomatic way to read after writing or is should I use `seek(0)` instead?
Michael Braxton
You should consider multiple things: first not all IO objects can be seeked, so reopening is sometimes the only option. But the Tempfile class is made to delete the created file after closing it (and after GC-ing it), and during the small timeframe of reopening it an other process might get a handle on it, which makes reopening more error-prone.
SztupY
+5  A: 

The problem is that you are doing a read at the current IO pointer in the file, which is already at the end after your writes. You need to do a rewind before the read. In your example:

require 'tempfile'
t = Tempfile.new('test-data')
t.open
t.sync = true
t << "apples"
t.puts "bananas"
t.rewind
puts "contents are [#{t.read}] (#{t.size} bytes)"
t.close
ScottD