R
Randy Kramer
Recently I've written several small utilities which are basically
filters--they read a file one line at a time, do something with one or more
of those lines, and write one or more lines to an output file.
(With help at various times from the list) I got those utilities working with
a nested block structure something like this:
File.open("output file", "w") do |f|
File.open("input file").each do |line|
do stuff
end
end
For the next somewhat similar utility, that won't work as well--I really want
to nest the blocks the other way (at least I think so ;-).
The difference (in required functionality) is that this time I need to split
the single input file into multiple output files (multiple entire records (of
varying size) not exceeding a specified maximum file size).
I can see how to do it something like this (beware the pseudo-code /
handwaving):
output_file_size = 0
f = File.open("output file")
File.for each("input_file", rec_sep) do |record|
if output_file_size + record.length <= max_file_size then
puts f.record
output_file_size = output_file_size + record.length
else
f.close
construct next output file name
output_file_size = 0
f = File.open(next output file)
end
f.close
end
But I wonder if there is a way to do it with a block for the output file.
(ignoring an approach using something like the following to write each record:
File.open("output file").each { |f| f.puts record}
which opens and closes each output file multiple times, once for each record
written.
)
More specifically, I'm wondering if there is a way to make something like this
work:
create output file name (-1--i.e., one less than desired file name)
File.for each("input file", rec_sep) do |record|
increment output file name #pretty sure this is not in the right place
File.open("output file").each do |f|
if output_file_size >= max_file_size then break end
puts f.record
end
end
Randy Kramer
filters--they read a file one line at a time, do something with one or more
of those lines, and write one or more lines to an output file.
(With help at various times from the list) I got those utilities working with
a nested block structure something like this:
File.open("output file", "w") do |f|
File.open("input file").each do |line|
do stuff
end
end
For the next somewhat similar utility, that won't work as well--I really want
to nest the blocks the other way (at least I think so ;-).
The difference (in required functionality) is that this time I need to split
the single input file into multiple output files (multiple entire records (of
varying size) not exceeding a specified maximum file size).
I can see how to do it something like this (beware the pseudo-code /
handwaving):
output_file_size = 0
f = File.open("output file")
File.for each("input_file", rec_sep) do |record|
if output_file_size + record.length <= max_file_size then
puts f.record
output_file_size = output_file_size + record.length
else
f.close
construct next output file name
output_file_size = 0
f = File.open(next output file)
end
f.close
end
But I wonder if there is a way to do it with a block for the output file.
(ignoring an approach using something like the following to write each record:
File.open("output file").each { |f| f.puts record}
which opens and closes each output file multiple times, once for each record
written.
)
More specifically, I'm wondering if there is a way to make something like this
work:
create output file name (-1--i.e., one less than desired file name)
File.for each("input file", rec_sep) do |record|
increment output file name #pretty sure this is not in the right place
File.open("output file").each do |f|
if output_file_size >= max_file_size then break end
puts f.record
end
end
Randy Kramer