【问题标题】:Ruby (Errno::EACCES) on File.delete - previous solution doesn't workFile.delete 上的 Ruby (Errno::EACCES) - 以前的解决方案不起作用
【发布时间】:2013-04-15 16:02:55
【问题描述】:

我遇到的问题与此问题的发帖人完全相同:Ruby (Errno::EACCES) on File.delete。与他不同的是,解决方案中为他提供的更改对我不起作用。

这是我的代码,它是一个压缩算法,我想删除原始文件:

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)

您会注意到其中有一对 puts 来确认 chmod 发生了什么。输出是这样的:

Number of files changed by CHMOD : 1

没有Something happened。因此运行 chmod 不会产生错误,并且 chmod 确实修改了一个文件(大概是 uncompressed_file。)但是,我仍然在删除行上得到 Errno::EACCESS 错误。

为什么我不能删除文件?!它把我逼到了墙角。我正在运行 Windows 8 和 ruby​​ 1.9.3。

编辑:下面的第一个答案解决了无法删除文件的问题;但是,它使我的代码尝试执行的工作无效(即,当我的文件通过解决方案中提供的压缩算法运行,然后通过我的其他算法运行时,文件恢复损坏)。是的,我也曾尝试在我的通货膨胀方法中模仿这里的编码风格,但这并没有帮助。以下是对我的文件执行加密、解密和解压缩的其余代码:

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

【问题讨论】:

    标签: ruby chmod delete-file


    【解决方案1】:

    我认为这可能与您没有正确关闭文件有关。我冒昧地重写了你的代码,没有 chmod 的东西(我认为没有必要)

    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)
    

    如您所见,我使用了 File.open(path) 并传递了一个块。这具有在块退出时自动关闭文件的效果。 我还更改了删除/重命名代码,只需将 gzip 文件移动到原始路径,效果相同。

    但是,我强烈建议您保留原始文件的备份。

    【讨论】:

    • 嗨,Sascha,非常感谢您的回复。它看起来非常优雅,代码确实允许我删除原始文件——但是,它会导致压缩文件失去完整性(在我加密、解密并再次解压缩之后)。我将使用其余代码更新原始问题。
    • 很高兴我至少可以帮助解决文件删除问题。
    • 原来,我的代码中的其他东西完全导致了完整性崩溃的问题。实际上,正是这个删除问题的修复暴露了另一个问题(它与路径有关)。再次感谢萨沙。
    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2019-11-03
    • 1970-01-01
    相关资源
    最近更新 更多