Странный Ruby IO с Tempfile - PullRequest
       43

Странный Ruby IO с Tempfile

8 голосов
/ 14 июля 2011

Это сводит меня с ума. Учтите следующее:

require 'open-uri'

#set up tempfile
extname = File.extname file_url
basename = File.basename(file_url, extname)
file = Tempfile.new([basename,extname])

#read form URI into tempfile
uri = URI.parse(file_url)
num_bytes_writen = file.write(uri.read)
puts "Wrote #{num_bytes_writen} bytes"

# Reading from my tempfile
puts "Opening: #{file.path} >>"
puts "#### BEGINING OF FILE ####"
puts  File.open(file.path,'rb').read
puts "#### END OF FILE ####"

Похоже, что записываются байты, но когда я пытаюсь открыть файл - он пуст. Как дела?!

И чтобы сделать это более странным - все работает в консоли Rails, но не при выполнении работником, запущенным Resque.

Есть идеи? Спасибо, ребята

Ответы [ 2 ]

16 голосов
/ 14 июля 2011

Это проблема буферизации. Вам нужно сбросить буфер ввода-вывода на диск, прежде чем пытаться его прочитать. Либо file.close (если вы закончили с этим), либо file.flush до выполнения File.open для чтения.

Обновление

Я не думал об этом, но вам не нужно открывать временный файл, чтобы просто прочитать его. Он уже открыт для записи и чтения , все, что вам нужно сделать, это искать начало файла перед чтением. Таким образом, вам не нужно делать сброс (потому что вы на самом деле читаете из буфера) ...

# starting partway into your code...
num_bytes_written = file.write(uri.read)
puts "Wrote #{num_bytes_written} bytes"

puts "No need to open #{file.path} >>"
puts "### BEGINNING OF FILE ###"

file.rewind         # set the cursor to the start of the buffer
puts file.read      # cursor is back at the end of the buffer now

puts "### END OF FILE ###"

Еще одно обновление

После комментария от @ carp я изменил приведенный выше код, чтобы использовать rewind вместо seek 0, потому что он также сбрасывает lineno в 0 (и без этого, если вы использовали lineno, это было бы очень сбивало с толку). Также на самом деле это более выразительное имя метода.

1 голос
/ 14 июля 2011

Всегда закрывайте свои файлы. Попробуйте использовать этот стиль в своем коде, чтобы избежать таких ошибок:

File.open(myfile,"w") {|f| f.puts content }

Таким образом, он автоматически вызовет close, когда закончится блок.

...