1

When I run the following code taken from the Learn Ruby the Hard Way Course Exercise 16,

filename = ARGV.first
target = open(filename, 'w+')

puts "Now I'm going to ask you for three lines."

print "line 1: "
line1 = $stdin.gets.chomp
print "line 2: "
line2 = $stdin.gets.chomp
print "line 3: "
line3 = $stdin.gets.chomp

puts "I'm going to write these to the file."

target.write(line1 + "\n" + line2 + "\n" + line3)

puts "And now I'm going to print the file to prove I have altered it."
puts target.read

puts "And finally, we close it."
target.close

the line puts target.read does not print the three input lines, even though the text file does change.

I have tried changing the mode used by the open method and adding a new open method before calling the read method. Creating a separate program with the same script to read and print text file works as expected.

How can I read a file I have just written to? Why does it not work when I write and read within the same program?

sawa
  • 165,429
  • 45
  • 277
  • 381
jonsanders101
  • 525
  • 1
  • 6
  • 13

2 Answers2

4

why does it not work when I write and read within the same program

The answer is that when you write to a file, your IO stream is set to the end of where you have written. When you read, it continues from this point. In this case, after writing, you have reached the end of the file and there is nothing else to 'read'. You can use IO#rewind to reroll to the beginning and print out what was just written to through the IO Stream.

filename = 'Test.txt'
target = open(filename, 'w+')

text  = '12345'
target.write(text) # target points to EOF
# Note that if you print target.write(), it will tell you the 'index' of where the IO stream is pointing. In this case 5 characters into the file.

puts "And now I'm going to rewind the file"
puts target.rewind # go back to the beginning of the file.
# => 0
puts "And now I'm going to print the file to prove I have rewound it."
puts target.read # read the file, target now points to EOF.
# => '12345'


target.close
whodini9
  • 1,434
  • 13
  • 18
-2
File.open("my/file/path", "r") do |f|
  f.each_line do |line|
    puts line
  end
end

File is closed automatically at end of block It is also possible to explicitly close file after as above (pass a block to open closes it for you):

f = File.open("my/file/path", "r")
f.each_line do |line|
  puts line
end
f.close

Credit to: https://stackoverflow.com/a/5545284/8328756

Leo Van Deuren
  • 435
  • 2
  • 10