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)
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.
Edit: As per Az's suggestion in the comments I added:
ObjectSpace.each_object(File) { |f| p f if f.path == @file_name && !f.closed? }
Just before the call to 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.
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.
To remedy this I used File.open do |file| file.each, instead of 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.