Issue
I am having exactly the same issue as the poster of this question : Ruby (Errno::EACCES) on File.delete. Unlike him, the change provided in the solution for him does not work for me.
Here is my code, it is a compression algorithm where I want to delete the original file :
uncompressed_file = File.new(Rails.root + filepath)
compressed_file = File.new(Rails.root + "#{filepath[0..filepath.size - 1]}.gz", "w+b")
file_writer = Zlib::GzipWriter.new(compressed_file)
buf = ""
File.open(uncompressed_file, "rb") do | uncompressed |
while uncompressed.read(4096, buf)
file_writer << buf
end
file_writer.close
end
begin
files_changed_by_chmod = File.chmod(0777, uncompressed_file)
rescue
puts "Something happened"
end
puts "Number of files changed by CHMOD : " + files_changed_by_chmod.to_s
File.delete(uncompressed_file)
File.rename(Rails.root + "#{filepath[0..filepath.size - 1]}.gz", Rails.root + filepath)
You'll notice there are a couple puts
in there to confirm what is happening with the chmod. The output is this :
Number of files changed by CHMOD : 1
and there is no Something happened
. Therefore there is no error generated by running the chmod, and chmod indeed modifies one file (presumably, the uncompressed_file
.) However, I still get the Errno::EACCESS error on the delete line.
Why can't I delete the files?! It's driving me up the wall. I'm running Windows 8 and ruby 1.9.3.
EDIT: The first answer below solves the issue of not being able to delete the files; however, it invalidates the job my code is trying to do (i.e, when my files are run through the compression algorithm supplied in the solution and then my other algorithms, the file comes back corrupted). Yes, I did also try to emulate the coding style here in my inflation method, but that didn't help. Here is the rest of the code that performs the encryption, decryption, and decompression of my files :
def inflate_attachment(filepath)
compressed_file = File.new(Rails.root + filepath)
File.open(compressed_file, "rb") do | compressed |
File.open(Rails.root + "#{filepath[0..filepath.size - 7]}_FULL.enc", 'w+b') do | decompressed |
gz = Zlib::GzipReader.new(compressed)
result = gz.read
decompressed.write(result)
gz.close
end
end
end
def encrypt_attachment(filepath, cipher)
unencrypted_file = File.new(Rails.root + filepath)
encrypted_file = File.new(Rails.root + "#{filepath[0..filepath.size - 1]}.enc", "w")
buf = ""
File.open(encrypted_file, "wb") do |outf|
File.open(unencrypted_file, "rb") do |inf|
while inf.read(4096, buf)
outf << cipher.update(buf)
end
outf << cipher.final
end
end
end
def decrypt_attachment(filepath, key, iv)
cipher = OpenSSL::Cipher.new(ENCRYPTION_TYPE)
cipher.decrypt
cipher.key = key
cipher.iv = iv
encrypted_file = File.new(Rails.root + filepath)
decrypted_file = File.new(Rails.root + "#{filepath[0..filepath.size - 5]}.dec", "w")
buf = ""
File.open(decrypted_file, "wb") do |outf|
File.open(encrypted_file, "rb") do |inf|
while inf.read(4096, buf)
outf << cipher.update(buf)
end
outf << cipher.final
end
end
end
Solution
I think that might have something to do that you haven't properly closed the files. I took the liberty to rewrite your code, without the chmod stuff (which I don't think is necessary)
filename = <your sourcefilename goes here>
filename_gz = filename + ".gz"
filepath = Rails.root + filename
filepath_gz = Rails.root + filename_gz
# gzip the file
buffer = ""
File.open(filepath) do |file|
Zlib::GzipWriter.open(filepath_gz) do |gz|
while file.read(4096, buffer)
gz << buffer
end
end
end
# moves the filepath_gz to filepath (overwriting the original file in the process!)
FileUtils.mv(filepath_gz, filepath)
As you can see I've used File.open(path) and passed a block. This has the effect that the files will be closed automatically when the block exits. I've also changed the delete/rename code to simply move the gziped file to the original path, which has the same effect.
However, I strongly advice you to keep a backup of your original file.
Answered By - Sascha Kaestle Answer Checked By - Timothy Miller (WPSolving Admin)