45

I am trying to create a Tempfile and write some text into it. But I get this strange behavior in console

t = Tempfile.new("test_temp") # => #<File:/tmp/test_temp20130805-28300-1u5g9dv-0>
t << "Test data"              # => #<File:/tmp/test_temp20130805-28300-1u5g9dv-0>
t.write("test data")          # => 9
IO.read t.path                # => ""

I also tried cat /tmp/test_temp20130805-28300-1u5g9dv-0 but the file is empty.

Am I missing anything? Or what's the proper way to write to Tempfile?

FYI I'm using ruby 1.8.7

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Siva
  • 7,780
  • 6
  • 47
  • 54
  • 2
    Figured it out `t.flush` is the perfect solution. – Siva Jun 16 '14 at 03:29
  • Why does this adds an extra string to the end of the file name. How can we remove this?the file name mentioned is test_temp, but generted test_temp20130805-28300-1u5g9dv-0 – Mahesh Mesta Sep 28 '22 at 10:16

4 Answers4

50

You're going to want to close the temp file after writing to it. Just add a t.close to the end. I bet the file has buffered output.

squiguy
  • 32,370
  • 6
  • 56
  • 63
  • 1
    Prefer to use blocks for file operations if possible, you won't have to remember to close it, it will do it for you. Using certain methods will also automatically close it or you as well. `IO.read` (`File.read`) is one of these methods, according to the documentation. "read ensures the file is closed before returning." – vgoff Aug 05 '13 at 08:37
  • I am pretty new to ruby and I had a similar issue here. I missed this issue I think because on a local machine it seemed to be working whereas when I test on a build server I was hitting the same issue. Any idea why this would fail intermittently? I am going to search around more as well but wanted to ask here first. – Elliott Jan 26 '18 at 16:40
23

Try this run t.rewind before read

require 'tempfile'
t = Tempfile.new("test_temp")
t << "Test data"
t.write("test data") # => 9
IO.read t.path # => ""
t.rewind
IO.read t.path # => "Test datatest data"
Debadatt
  • 5,935
  • 4
  • 27
  • 40
9

close or rewind will actually write out content to file. And you may want to delete it after using:

file = Tempfile.new('test_temp')
begin
  file.write <<~FILE
    Test data
    test data
  FILE
  file.close

  puts IO.read(file.path) #=> Test data\ntestdata\n
ensure
  file.delete
end
Lev Lukomsky
  • 6,346
  • 4
  • 34
  • 24
8

It's worth mentioning that calling .rewind is a must or otherwise any subsequent .read call will just return an empty value.

Artur INTECH
  • 6,024
  • 2
  • 37
  • 34