Forum: Ruby Tempfile : delete problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C667185722eaecf12461cb423dc8b410?d=identicon&s=25 Ronald Fischer (Guest)
on 2007-07-12 13:55
(Received via mailing list)
(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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-12 15:31
(Received via mailing list)
2007/7/12, Ronald Fischer <ronald.fischer@venyon.com>:
>     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
C667185722eaecf12461cb423dc8b410?d=identicon&s=25 Ronald Fischer (Guest)
on 2007-07-12 15:51
(Received via mailing list)
> >
>
> 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):

   1. create temporary file
   2. fill temporary file and close it
   3. rename it, so that it ends in .xml
   4. pass its file name to some library function, which processes the
file
   5. 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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-12 16:04
(Received via mailing list)
2007/7/12, Ronald Fischer <ronald.fischer@venyon.com>:
> > >
> >
> > 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.

>    5. 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
C667185722eaecf12461cb423dc8b410?d=identicon&s=25 Ronald Fischer (Guest)
on 2007-07-16 10:39
(Received via mailing list)
> 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-mogri...
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
Ee469623eb1b8e6e35d192822b9c4aa2?d=identicon&s=25 Florian Aßmann (Guest)
on 2007-07-16 11:12
(Received via mailing list)
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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-16 11:32
(Received via mailing list)
2007/7/16, Florian Aßmann <florian.assmann@email.de>:
> 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
C667185722eaecf12461cb423dc8b410?d=identicon&s=25 Ronald Fischer (Guest)
on 2007-07-16 14:15
(Received via mailing list)
> 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
This topic is locked and can not be replied to.