(Ruby 1.8.6 under Windows)
My application creates a series of temporary files. I decided to use
the tempfile module of Ruby, but I needed to control the file extension
of the generated temporary file (should end in .xml). I came up with
the following solution:
file=Tempfile.new('.tempreq','/thome/requests')
file << '....' # populate the file
path=file.path # remember the generated filename
file.close
result=path+'.xml' # add desired extension to the filename
File.rename(path,result) # rename file
at_exit { File::delete(result) } # remove file at exit
When the exit handler jumps into action, I get however the following
error:
H:\thome\grubylib/TfwCommon.rb:433:in `delete’: Permission denied -
/thome/requests/.tempr
eq.3176.0.xml (Errno::EACCES)
After the program has ended, I can however erase the file from the
command line with
no problems. Why do I get a “permission denied” here? Is there a better
way to
achieve my goal?
Ronald
I’d just use the block form:
ruby -r tempfile -e ‘Tempfile.open(“foo”, “.”) {|io| io.puts 123}’
Hmmm… I don’t see how this solves my file rename problem. Don’t forget
that I need to rename the temporary file, so that it has the extension
.xml, before I continue processing it. The logic basically should go
like this (pseudocode):
- create temporary file
- fill temporary file and close it
- rename it, so that it ends in .xml
- pass its file name to some library function, which processes the
file
- when my application exits, delete that xml file
Tempfile::open with block argument performs steps 1 and 2 above, but
doesn’t
tell me the name of the temporary file:
x=Tempfile.open(“foo”, “.”) {|io| io.puts 123}
x.class
=> NilClass
2007/7/12, Ronald F. [email protected]:
I’d just use the block form:
ruby -r tempfile -e ‘Tempfile.open(“foo”, “.”) {|io| io.puts 123}’
Hmmm… I don’t see how this solves my file rename problem.
Ah, my bad: I overread that one. File renaming is a bad idea with
tempfiles.
- when my application exits, delete that xml file
Tempfile::open with block argument performs steps 1 and 2 above, but
doesn’t
tell me the name of the temporary file:
x=Tempfile.open(“foo”, “.”) {|io| io.puts 123}
x.class
=> NilClass
In that case rather use your own mechanism. That’s too far away from
tempfile’s functionality. For example
def tmp_xml(base, dir, mode)
file_name = File.join(dir, “#{base}-#{rand 1000}.xml”)
begin
File.open(file_name, mode) do |io|
yield io, file_name
end
ensure
File.unlink file_name if File.exists? file_name
end
end
Then you can do
tmp_xml “.”, “foo”, “rw” do |io, name|
puts “file is #{name}”
…
end
Kind regards
robert
the following
error:
H:\thome\grubylib/TfwCommon.rb:433:in `delete’:
Permission denied -
/thome/requests/.tempr
eq.3176.0.xml (Errno::EACCES)
In that case rather use your own mechanism. That’s too far away from
tempfile’s functionality.
I found a solution based on an idea posted at
http://marsorange.com/articles/2006/07/17/of-mogrify-ruby-tempfile-dynam
ic-class-definitions
which allowed me to use most of Tempfile functionality with only
providing
minimal own code:
require ‘tempfile’
class XMLTempfile <Tempfile
def make_tmpname(basename, n)
sprintf(‘%s%d-%d.xml’, basename, $$, n)
end
end
…
file=XMLTempfile.new('.tempreq',TFW_REQDIR)
file << '.....'
result=file.path
file.close
Ronald
2007/7/12, Ronald F. [email protected]:
file.close
After the program has ended, I can however erase the file from the
command line with
no problems. Why do I get a “permission denied” here? Is there a better
way to
achieve my goal?
I’d just use the block form:
ruby -r tempfile -e ‘Tempfile.open(“foo”, “.”) {|io| io.puts 123}’
After that there is no file prefixed “foo” in “.”.
Kind regards
robert
2007/7/16, Florian Aßmann [email protected]:
Hi Ronald,
clarification: accessing a path of an IO can be done through
Tempfile#path, it’s standard for File…
Thanks for catching that! I looked for something like this but
apparently /over/looked it. 
Cheers
robert
renamed the file.
Thank you, this makes things clear now.
Why do you need the .xml suffix?
Because I have an application which accepts a basename for a file,
and implicitly assumes its extension .xml.
Ronald
Hi Ronald,
clarification: accessing a path of an IO can be done through
Tempfile#path, it’s standard for File…
require ‘tempfile’
Tempfile.open(’’) { |tempfile| puts tempfile.path }
and since tempfile is per default deleted when the object becomes
finalized it fails because the path is invalid after you renamed the
file.
Why do you need the .xml suffix?
Regards
Florian