开发者

Base64 encoded string to file(Ruby on Rails)

I have a requirement where a zip file is sent to the ROR application after encoding it with Base64 encoding. I should decode it, save it as a zipfile and unzip it and do some operations. They are sending the zip file encoded data as a parameter called zip through POST method. Here, is what I have done in code.

require 'rubygems'
require 'zip/zip'
require 'base64'

def get_pdf
  encoded_data = Base64.decode64(params[:zip])
  File.open("#{RAILS_ROOT}/zip_archive/zip_file.zip", "w") {|f| f.write encoded_data}
  unzip_file("#{RAILS_ROOT}/zip_archive/zip_file.zip", "#{RAILS_ROOT}/unzipped/")
  ...(using @file_path, do stuff)
end

def unzip_file (file, destination)
  destination = File.join(destination, File.basename(file, ".zip"))
  Zip::ZipFile.open(file) { |zip_file|
    zip_file.each { |f|
      f_path=File.join(destination, f.name)
      FileUtils.mkdir_p(File.dirname(f_path))
      zip_file.extract(f, f_path) unless File.exist?(f_path)
    }
  }
  @file_path = destination
end

But, I am not able to save the zip file correctly. The fi开发者_Python百科le after saving is giving error on the unzipping part.

Zip::ZipError (Zip end of central directory signature not found):
  rubyzip (0.9.4) lib/zip/zip.rb:1287:in `get_e_o_c_d'
  rubyzip (0.9.4) lib/zip/zip.rb:1235:in `read_e_o_c_d'
  rubyzip (0.9.4) lib/zip/zip.rb:1260:in `read_from_stream'
  rubyzip (0.9.4) lib/zip/zip.rb:1392:in `initialize'
  rubyzip (0.9.4) lib/zip/zip.rb:1392:in `open'
  rubyzip (0.9.4) lib/zip/zip.rb:1392:in `initialize'
  rubyzip (0.9.4) lib/zip/zip.rb:1410:in `new'
  rubyzip (0.9.4) lib/zip/zip.rb:1410:in `open'
  app/controllers/pdf_controller.rb:37:in `unzip_file'
  app/controllers/pdf_controller.rb:13:in `get_pdf'

When I tried to open the file outside the app also, the file was not getting opened saying

[/home/prince/Desktop/test_project/zip_archive/zip_file.zip]
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
zipinfo:  cannot find zipfile directory in one of /home/prince/Desktop/test_project/zip_archive/zip_file.zip or
          /home/prince/Desktop/test_project/zip_archive/zip_file.zip.zip, and cannot find /home/prince/Desktop/test_project/zip_archive/zip_file.zip.ZIP, period.

I tried saving the file with File.open("..", "wb") to write the contents in the binary mode, but then also the same error occurs. Should I do anything to the params[:zip] before decoding it?


Works like a charm. The File#open block should properly write and close the file, you're probably just having the wrong path in there somewhere. If the File.exists? and the decode64 went through, you should be good.

ruby-1.9.2-p0 > zip = "UEsDBAoAAAAAAKphcT4AAAAAAAAAAAAAAAAFABwAZW1wdHlVVAkAA8/sgU3P\n7IFNdXgLAAEE9QEAAAQUAAAAUEsBAh4DCgAAAAAAqmFxPgAAAAAAAAAAAAAA\nAAUAGAAAAAAAAAAAAKSBAAAAAGVtcHR5VVQFAAPP7IFNdXgLAAEE9QEAAAQU\nAAAAUEsFBgAAAAABAAEASwAAAD8AAAAAAA==\n"
ruby-1.9.2-p0 > File.open('test2.zip', 'wb') {|f| f.write(Base64.decode64(zip))}
 => 160 
ruby-1.9.2-p0 > Zip::ZipFile.open('test2.zip') {|z| z.each {|f| puts f.name}}
empty
 => [empty] 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜