# Write output to multiple files

**URL:** <https://www.ruby-forum.com/t/write-output-to-multiple-files/166290>\
**Category:** Ruby\
**Created:** [April 23, 2009, 4:20pm UTC](https://www.ruby-forum.com/t/write-output-to-multiple-files/166290 "2009-04-23T16:20:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![milo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@milo](https://www.ruby-forum.com/u/milo)\
**Post date:** [April 23, 2009, 4:20pm UTC](https://www.ruby-forum.com/t/write-output-to-multiple-files/166290/1 "2009-04-23T16:20:14Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![milo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@milo](https://www.ruby-forum.com/u/milo)\
**Post date:** [April 23, 2009, 6:45pm UTC](https://www.ruby-forum.com/t/write-output-to-multiple-files/166290/2 "2009-04-23T18:45:53Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![milo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@milo](https://www.ruby-forum.com/u/milo)\
**Post date:** [April 23, 2009, 6:48pm UTC](https://www.ruby-forum.com/t/write-output-to-multiple-files/166290/3 "2009-04-23T18:48:17Z")

</div>

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.
