简体   繁体   English

File.delete引发Errno:EACCESS权限在ruby中被拒绝

[英]File.delete throws Errno:EACCESS Permission Denied in ruby

The following code that is meant to delete lines that match a regular expression fails 以下旨在删除与正则表达式匹配的行的代码失败

def delete_entry(name)
    puts "Deleting #{name}.." if $DEBUG
    begin
      File.open("#{@file_name}.tmp", 'w') do |out_file|
        File.open(@file_name, 'r').each do |line|
          unless line =~ /^#{name},/
            out_file.print line
          else
            puts "Deleted #{line}!"
          end
        end
      end
      File.delete(@file_name)
      File.rename("#{@file_name}.tmp", @file_name)
    rescue Exception
      puts "Exception thrown in PhoneBook::delete_entry(#{name}): #{$!}"
    end
  end

The temporary file works just fine. 临时文件可以正常工作。 The corresponding entries are deleted properly. 相应的条目已正确删除。 But when I try to delete the old file, and rename the tmp to the new file, File.delete throws the following: (line 56 is the call to File#delete) 但是,当我尝试删除旧文件并将tmp重命名为新文件时,File.delete引发以下内容:(第56行是对File#delete的调用)

Exception `Errno::EACCES' at PhoneBook.rb:56 - Permission denied - file-io-sampl
es/phonebooks/test.csv
Exception thrown in PhoneBook::delete_entry(Mike): Permission denied - file-io-s
amples/phonebooks/test.csv

Any help would be appreciated. 任何帮助,将不胜感激。 This is on Windows 7 using a NTFS filesystem if that helps matters. 如果有帮助的话,这是在Windows 7上使用NTFS文件系统的。

Edit: As per Az's suggestion in the comments I added: 编辑:根据我在评论中添加的Az建议:

ObjectSpace.each_object(File) { |f| p f if f.path == @file_name && !f.closed? }

Just before the call to File.delete. 就在调用File.delete之前。 The output is below: 输出如下:

C:\Pickaxe>ruby PhoneBook.rb true
Enter a phonebook!
test.csv
Using test.csv..
Open Called!
Name: Richard Sex: Male Age: 22
Name: Midori Sex: Female Age: 22
Name: Mike Sex: Male Age:  18
Name: Richard Sex: Male Age: 44
Deleting Mike..
Deleted Mike,Male, 18
!
#<File:file-io-samples/phonebooks/test.csv>
#<File:file-io-samples/phonebooks/test.csv>
Exception `Errno::EACCES' at PhoneBook.rb:56 - Permission denied - file-io-sampl
es/phonebooks/test.csv
Exception thrown in PhoneBook::delete_entry(Mike): Permission denied - file-io-s
amples/phonebooks/test.csv

C:\Pickaxe>

The two lines prefixed with # is the output of the ObjectSpace call. 带有#前缀的两行是ObjectSpace调用的输出。

I figured this out as I stated my last comment on the original post. 我在对原始帖子发表最后评论时想出了这一点。 The problem was is I wasn't calling open with a block and therefore did not benefit from the automatic f.close that comes with using File.open with a block. 问题是我不是用块调用open,因此不能从使用File.open和块一起使用的自动f.close中受益。

To remedy this I used File.open do |file| 为了解决这个问题,我使用File.open do | file | file.each, instead of File.open(..).each file.each,而不是File.open(..)。each

def delete_entry(name)
    puts "Deleting #{name}.." if $DEBUG
    begin
      File.open("#{@file_name}.tmp", 'w') do |out_file|
        File.open(@file_name, 'r+') do |file|
          file.each do |line|
            unless line =~ /^#{name},/
              out_file.print line
            else
              puts "Deleted #{line}!"
            end
          end
        end
      end
      ObjectSpace.each_object(File) { |f| p f if f.path == @file_name && !f.closed? } if $DEBUG
      File.delete(@file_name)
      File.rename("#{@file_name}.tmp", @file_name)
    rescue Exception
      puts "Exception thrown in PhoneBook::delete_entry(#{name}): #{$!}"
    end
  end

As a general tip to anyone who finds this while trying to diagnose the error themselves, try deleting the file manually via the command line first. 作为对自己尝试诊断错误时发现此错误的任何人的一般提示,请尝试首先通过命令行手动删除文件。 That may show you that you have permissions issues on the file. 这可能表明您在文件上存在权限问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM