Problem with creating/deleting file in same process (Windows)

Discussion in 'Ruby' started by Mike Grier, Dec 18, 2004.

  1. Mike Grier

    Mike Grier Guest

    I'm new to ruby so perhaps I'm simply doing this wrong, but...

    Has anyone else encountered a problem with attempting to create
    and then delete a file in the same process when using ruby on
    Windows? Below is a test case that illustrates the problem; the
    test_delete_file fails with a permission denied error.

    My ruby version is 'ruby 1.8.2 (2004-07-29) [i386-mswin32]',
    though I've also seen the problem with the cygwin version.

    I'm assuming this test would pass on linux/unix (I unfortunately
    don't have access to one that has ruby loaded). It appears that
    windows is locking the file until the test process ends.
    However, if I create the file in a child process using a system
    call I can delete it in the parent process.

    For my immediate needs I can create the files in a child process,
    perhaps overridng File.new to do it, but does anyone have
    suggestions as to the best way to handle this? Is this a bug in
    the windows version of ruby (i.e. could it be implemented to
    allow the delete in the same process)?

    Thanks in advance,

    Mike


    #!/usr/bin/env ruby

    require 'fileutils'
    require 'test/unit'
    require 'tmpdir'

    include FileUtils::Verbose

    class TestFileDelete < Test::Unit::TestCase

    TMP_DIR = Dir.tmpdir
    # TMP_DIR = "C:/tmp"

    TEST_DIR = TMP_DIR + "/tdir"
    TEST_FILE_1 = TMP_DIR + "/tfile1"
    TEST_FILE_2 = TMP_DIR + "/tfile2"

    # Clean up the files from the previous run, do this here rather
    # than setup so it only happens once.

    FileUtils.rm_rf(TEST_DIR) if File.exists?(TEST_DIR)
    FileUtils.rm_rf(TEST_FILE_1) if File.exists?(TEST_FILE_1)
    FileUtils.rm_rf(TEST_FILE_2) if File.exists?(TEST_FILE_2)

    def teardown
    # Won't attempt to clean up in same process
    end

    def test_delete_dir
    assert(!File.exists?(TEST_DIR),"Test dir already exists")

    Dir.mkdir(TEST_DIR)

    assert(File.exists?(TEST_DIR))

    FileUtils.rm_rf(TEST_DIR)

    assert(!File.exists?(TEST_DIR),"Unable to delete test dir")
    end

    def test_delete_file
    assert(!File.exists?(TEST_FILE_1),"Test file already exists")

    File.new(TEST_FILE_1,File::CREAT,0666)

    assert(File.exists?(TEST_FILE_1))

    begin
    FileUtils.rm_rf(TEST_FILE_1)
    rescue SystemCallError => e
    puts "\nError on attempt: FileUtils.rm_rf (" + e + ")"
    end

    begin
    File.delete(TEST_FILE_1)
    rescue SystemCallError => e
    puts "\nError on attempt: File.delete (" + e + ")"
    end

    begin
    system("rm -rf " + TEST_FILE_1);
    rescue SystemCallError => e
    puts "\nError on attempt: system rm -rf (" + e + ")"
    end

    assert(!File.exists?(TEST_FILE_1),"Unable to delete test file")
    end

    def test_delete_file_in_child_process
    assert(!File.exists?(TEST_FILE_2),"Test file already exists")

    system("ruby -e 'File.new(\"" + TEST_FILE_2 + "\",File::CREAT)'")

    File.delete(TEST_FILE_2)

    assert(!File.exists?(TEST_FILE_2),"Unable to delete test file")
    end

    end
     
    Mike Grier, Dec 18, 2004
    #1
    1. Advertising

  2. Mike Grier

    Justin Rudd Guest

    > I'm new to ruby so perhaps I'm simply doing this wrong, but...

    This is more of a Windows thing than a Ruby thing.

    > File.new(TEST_FILE_1,File::CREAT,0666)


    Underneath the covers this opens a handle to the file. Until that
    handle is closed, no one else can do anything to it. The GC will
    eventually get it. But probably not before your call to rm_rf

    > system("ruby -e 'File.new(\"" + TEST_FILE_2 + "\",File::CREAT)'")


    This works because when the process ends, the Ruby GC is probably
    called. If it isn't, then Windows will clean up the misbehaving
    process.

    --
    Justin Rudd
    http://seagecko.org/thoughts/
     
    Justin Rudd, Dec 19, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luis Esteban Valencia Muñoz
    Replies:
    3
    Views:
    1,414
    Scott Allen
    Jun 4, 2005
  2. master007
    Replies:
    8
    Views:
    838
    Oliver Wong
    Mar 6, 2006
  3. Harry Barker
    Replies:
    2
    Views:
    520
    Alf P. Steinbach
    Apr 19, 2006
  4. franckspike
    Replies:
    1
    Views:
    328
    Boris
    Jul 3, 2008
  5. crea
    Replies:
    2
    Views:
    417
    Nobody
    Dec 28, 2012
Loading...

Share This Page