以下用于删除与正则表达式匹配的行的代码失败
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
临时文件工作得很好。相应的条目将被正确删除。但是当我尝试删除旧文件,并将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
任何帮助将不胜感激。这是在Windows 7上使用NTFS文件系统,如果这有帮助的话。
编辑:根据Az在评论中的建议,我补充道:
ObjectSpace.each_object(File) { |f| p f if f.path == @file_name && !f.closed? }
在调用File.delete之前。 输出如下:
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>
前缀为#的两行是ObjectSpace调用的输出。
答案 0 :(得分:2)
我在原帖子上发表了我的最后评论时想到了这一点。问题是我没有用块调用open,因此没有受益于使用File.open和块一起使用的自动f.close。
为了解决这个问题,我使用了File.open do | file | file.each,而不是File.open(..)。每个
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
答案 1 :(得分:1)
作为在尝试自行诊断错误时发现此问题的任何人的一般提示,请先尝试通过命令行手动删除该文件。这可能会向您显示该文件存在权限问题。