Adrien
Adrien

Reputation: 2226

How to duplicate a File as a TempFile?

I am currently developing a script that look for files in a specific folder. I want to duplicate those files. Then I want to remove some useless lines from those duplicate files, parse them in YAML (this is the format of content in it). And finally make a diff of the files.

I was firstly thinking to copy them in a tmp folder but I just discovered the existence of Tempfile which seems to be exactly what I need since the temporary files have to be deleted after the script has done its job.

What I have for now:

require 'Tempfile'
require 'YAML'

PWD = File.dirname(__FILE__)
LOCALES_FOLDER_PATH = "#{PWD}/../app/assets/javascripts/ayl/bo/config/locales"
LOCALES = ['en', 'fr']

files_data = {}
locale_file_names = LOCALES.map{|locale| "#{locale}.js.coffee"}
files = locale_file_names.map do |locale_file_name|
  files_data[locale_file_name] = "#{LOCALES_FOLDER_PATH}/#{locale_file_name}"
end

locale_files = []
files.each do |file|

  content = File.open(file).read
  locale_file = Tempfile.open file.gsub("/", "_") do |f|
    f.write content
    f.flush
    puts f.read
  end
  locale_files << locale_file

end

Results in:

± ruby diff_locales.rb
/Users/adrien/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/YAML.rb:48: warning: already initialized constant ENGINE
/Users/adrien/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/YAML.rb:69: warning: already initialized constant ENGINE
/Users/adrien/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/YAML.rb:73: warning: already initialized constant ENGINE


±

The content of my temporary files is empty.

This seems weird to me. But I assume their is something I just do not know/understand.


OK! Figured it out! Inside the block, I had to move the cursor back to the beginning of the file before reading the content.

Upvotes: 4

Views: 4759

Answers (3)

Adrien
Adrien

Reputation: 2226

Inside the block, I had to move the cursor back to the beginning of the file before reading the content.

Upvotes: 1

sylvain.joyeux
sylvain.joyeux

Reputation: 1699

all ruby IO is buffered by default. You can either call #flush on the IO to write everything to disk, then calling #read is going to work. Closing a tempfile is going to delete it (that's the point).

Moreover, you should really prefer the block version of Tempfile.open, as it guarantees that the temporary file is closed and deleted when the block quits (instead of keeping it open as long as the program runs)

Upvotes: 0

bioneuralnet
bioneuralnet

Reputation: 5311

Try locale_file.close after write in your block. I don't believe the content is necessarily flushed to disk until then.

Upvotes: 0

Related Questions