Write output to multiple files


#1

I have encountered something I thought would be trivial but I can’t
quite get it to work properly. I have a load of data that is stored in
various locations and need to create several files, one for each
location, each containing the data in that location. Getting an array of
objects containing the file name and location is easy, so I was thinking
along the lines of this pseudocode:

data.each do |d|
output_filename = “#{d.location}.txt”
if !File.exists?(output_filename)
# create it and write d.file_name to it
else
# simply write d.file_name to it
end
end

close all open files

The locations of the data are numerical ids so I could expect filenames
like 1.txt, 2.txt and so on, and I have also sorted them before
processing so that they could be opened and filled sequentially. But, it
is not clear to me how to properly manage the file handles so any
suggestions would be welcome.


#2

On 23.04.2009 16:20, Milo T. wrote:

# create it and write d.file_name to it

suggestions would be welcome.
If I understood you properly:

untested

last_name = nil
io = nil
begin
data.sort_by {|d| d.location}.each do |d|
output_filename = “#{d.location}.txt”

 unless output_filename == last_name
   io.close rescue nil
   io = File.open(output_filename, "a")
 end

 io.puts d.file_name

ensure
io.close rescue nil
end

If you want to keep ‘data’ unsorted you might want to store IO objects
in a Hash, e.g.

files = Hash.new {|h,k| h[k] = File.open(k, “a”)}
begin
data.each do |d|
output_filename = “#{d.location}.txt”
files[output_filename].puts d.file_name
end
ensure
files.each do |k,io|
io.close rescue nil
end
end

Kind regards

robert


#3

Robert K. wrote:

If I understood you properly:

untested

last_name = nil
io = nil
begin
data.sort_by {|d| d.location}.each do |d|
output_filename = “#{d.location}.txt”

 unless output_filename == last_name
   io.close rescue nil
   io = File.open(output_filename, "a")
 end

 io.puts d.file_name

ensure
io.close rescue nil
end

Yes, that looks like just the job, thanks. I was trying something
similar but without the begin/ensure/end block and that is presumably
why I was having difficulty.