rubyzipを使ってzip圧縮を実装する。
Rubyスクリプト内での実装。
rubyzipを使ってZIP圧縮を書いたのだが、
単純なZIP圧縮処理を書くところで思いがけず時間をかけてしまったので、
自身への振り返りとして備忘録がてら圧縮処理を書いていく。
基本的に、Githubリポジトリ内の"Usage"を参考にしている。
下記を書いてbundle install。
gem 'rubyzip'
コードは下記の通りでrequireしてから実装していく
require 'zip'
def self.create_zip_archive # カレントディレクトリ配下にある"zip_target"内のファイルをZIPにまとめる # カレントディレクトリ配下にある"output"ディレクトリ内に現在の日付時刻のzipファイルを作成する target_files_path = "#{Dir::pwd}/zip_target" file_name = Time.now.strftime("%Y%m%d-%H%M.zip") output_zip_path = "#{Dir::pwd}/output/#{file_name}" # "zip_target"内のファイル名をArrayクラスに格納していく target_files = [] Dir.glob("#{target_files_path}/*.*").each do |i| target_files.push(File.basename(i)) end # zip archiveを作成する Zip::File.open(output_zip_path, Zip::File::CREATE) do |zipfile| target_files.each do |file| zipfile.add(file, "#{target_files_path}/#{file}") end end end
Ruby on Railsでの実装
DBから取得した投稿データ(postdata)を、
StringIOを使ってテキストファイルに書き込み、
そのファイルをZIP圧縮処理して、
"output"配下にエクスポートするという流れ。
ちなみにRailsのVersionは5を使用している。
Controllerでの処理。
対応するユーザIDの投稿データをDBから取得して、
それらのデータをまとめてZIP圧縮しようとしている。
実際のZIP圧縮処理はModel内に記載。
def export_zip postdata = Post.where(user_id: params[:id]) Post.export_zip_archive(postdata) render :export_zip end
Modelでの処理。
こちらで実際にZIP圧縮を行っている。
require 'zip' require 'stringio' def self.export_zip_archive(postdata) buf = StringIO.new # DBから取得したデータを書き込む postdata.each do |i| buf.puts(i.id) buf.puts(i.content) buf.puts(i.user_id) buf.puts(i.created_at) buf.puts(i.updated_at) buf.puts("\n") end filename = Time.now.strftime("%Y%m%d-%H%M") output_zip_path = "#{Rails.root}/output" FileUtils.mkdir_p(output_zip_path) unless FileTest.exist?(output_zip_path) # テキストファイルに書き込む file_name = "#{output_zip_path}/#{filename}.txt" File.open(file_name, "w") do |i| i.puts(buf.string) end # 書き込んだテキストファイルを対象にZIP圧縮処理を行う Zip::File.open("#{output_zip_path}/#{filename}.zip", Zip::File::CREATE) do |zipfile| zipfile.add(File.basename(file_name), file_name) end # テキストファイルは削除する FileUtils.rm(file_name) end
初心者感あふれる実装だと書いたものを見返してみて思う。
もう少しスマートに、そしてスピード感を持って実装を行っていきたいと思う、今日この頃。
ちょっと時間が経ってから、見返してリファクタリングしよう。