From: James Dinkel Date: 2009-05-02T05:33:36+09:00 Subject: Re: Read and re-write file with one open? timr wrote: > On Apr 29, 9:27�pm, Adam Bender wrote: > > Truncates file to at most integer bytes. The file must be opened for > writing. Not available on all platforms. > > f = File.new("out", "w") > f.syswrite("1234567890") #=> 10 > f.truncate(5) #=> 0 > f.close() #=> nil > File.size("out") #=> 5 That's pretty close to how I've been modifying files: File.open(filename, 'r+') do |file| lines = file.readlines # modify data in the lines array file.pos = 0 file.print lines # will not put \$ between array elements file.truncate(file.pos) end This opens a file for reading and writing, reads the file into an array, then you modify the array how you need to. Then the block returns to the beginning of the file, writes out your changes over the existing file, then chops off what's left. Then, of course, the file is closed when the block exits. To get a little more complicated, I wrapped this in a class method: class File def self.change!(filename, create = false) ### method to make it easy to open a file and make changes to it. ### usage example ## File.change(myfile) do |contents| ## contents.gsub!(/this/, "that") ## end ### I can also use "throw(:nochanges)" anywhere in the block ### to prevent the file from being written. ### Make sure 'contents' does not get pointed to a new object; ### for example, an assignemt "contents = 'new data'" will break the method # if create is true, create the file if it does not exist if create == true File.open(filename, 'w') { |blank| blank.write '' } unless File.exist?(filename) end # read the file, execute a block, then write the file if File.exist?(filename) File.open(filename, 'r+') do |file| lines = file.readlines # do not write the file if it did not change (block must "throw :nochanges") catch(:nochanges) do yield lines file.pos = 0 file.print lines # will not put \$ between array elements file.truncate(file.pos) end end end end end -- Posted via http://www.ruby-forum.com/.