フォームでzipファイルを入れて送信するとコントローラで解凍し、中に入っていたファイルをproducts_image1 ~ products_image30カラムに格納する機能を作っています。
##環境
macOS High Sierra(バージョン10.13.6)
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin17]
Rails 4.2.6
rubyzip (1.2.2)
##試したこと
zipファイル内にはフォルダが5つあり、それぞれフォルダ名を「1」「2」「3」「4」「5」にしています。理由は、このフォルダの番号順にレコードを作成したいからです。
ちなみにフォルダ1に入っているファイルは1つ、フォルダ2に入っているファイルも1つ、フォルダ3からフォルダ5までに入っているファイルは複数あります。
ruby
1def create 2 @product = Product.new(product_params) 3 p "1111111111111111111111111111111" 4 p product_params[:zip] 5 p "1111111111111111111111111111111" 6 7 Zip.unicode_names = true 8 Zip.force_entry_names_encoding = 'UTF-8' 9 10 zipfile = product_params[:zip] 11 Zip::File.open(zipfile.path) do |zip| 12 num = 0 13 zip.each do |entry| 14 entry.name.force_encoding('UTF-8') 15 entry_name = entry.name.encode("UTF-16BE", "UTF-8", :invalid => :replace, :undef => :replace, :replace => '?').encode("UTF-8") 16 p "aaaaaaaaaaaaaaaaaaaaaaaaaaa" 17 p entry_name 18 p "aaaaaaaaaaaaaaaaaaaaaaaaaaa" 19 ext = File.extname(entry_name) #拡張子を取得 20 # 隠しファイルやゴミファイルは飛ばす 21 next if ext.blank? || File.basename(entry_name).count(".") > 1 22 23 num += 1 24 if num > 30 then 25 break 26 end 27 28 # 一時ファイルを作る 29 Tempfile.open(["tempProductImageFile", ext]) do |t| 30 entry.extract(t.path) { true } 31 @product.send("products_image#{num}=", t) 32 end 33 end 34 end 35 end
以上のコードを実行して、実際に画像ファイルを見ると、zipファイルを作った時の順番ではありませんでした。
rails s でログを見てみると、
"1111111111111111111111111111111" #<ActionDispatch::Http::UploadedFile:0x007fbfa9b5e440 @tempfile=#<Tempfile:/var/folders/zx/41df886555n2m1gp6mqb0kkh0000gn/T/RackMultipart20181221-75747-1in4i5x.zip>, @original_filename="images.zip", @content_type="application/zip", @headers="Content-Disposition: form-data; name=\"product[zip]\"; filename=\"images.zip\"\r\nContent-Type: application/zip\r\n"> "1111111111111111111111111111111" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/1/?n?C?g???W?????[_ _?O??-2.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/1/" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_????@?u??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[__?S?~?u??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?u???[?J?[.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?C???^?[?z???????R??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?①?ɒu??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?K?X?x???.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?R?????u??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?V???N.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_????.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?G?A?R???????R??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_???ʑ?.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[__???ԏ?.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/?n?C?g???W?????[_ 203_?G?A?R??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/4/" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_???t?g-1.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?m??-4.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_???t?g-2.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?m??-5.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?m??-1.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?L?b?`??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?C???^?[?z??(????).jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?m??-2.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?m??-3.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_???փh?A.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?o???R?j?[-1.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?o???R?j?[-2.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?N???[?[?b?g.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?C??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_????.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/?n?C?g???W?????[_ 203_?g?C??.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/3/" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaa" "images/2/?n?C?g???W?????[_-203_?Ԏ??}.jpg" "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
*このアクション自体は成功しますが、意図した順番とはちがいます。
##問題点
- UTF-8にするコードを書いているが文字化けしている
- 呼び出される順番がimages/1のファイル → images/1 → images/4のファイル → images/4 といったように、意図した順番にならない
- images/5もimages/5内にあるファイルも呼ばれていない(実際には格納されている)
何が原因なのかわかりません。そもそもzipファイル内のファイルを意図した順番で並べることが不可能なのでしょうか?
なにかご教示いただけることがあれば、何卒よろしくお願いいたします。
##追記
zip.each do |entry|の中でencodingのコードを追加しましたが、問題点に変化がありません。
ruby
1 Zip::File.open(zipfile.path) do |zip| 2 num = 0 3 zip.each do |entry| 4 unless entry.name.valid_encoding? 5 entry.name.force_encoding case NKF.guess(entry.name) 6 when NKF::EUC then 'euc-jp' 7 when NKF::SJIS then 'cp932' 8 when NKF::UTF8 then 'utf-8' 9 when NKF::UTF16 then 'utf-16' 10 when Encoding::EUCJP_MS then Encoding::EUCJP_MS 11 when Encoding::CP51932 then Encoding::CP51932 12 when Encoding::WINDOWS_31J then Encoding::WINDOWS_31J 13 else 14 # JISコードもしくは不明 15 raise "文字コードが想定外です" 16 end 17 entry.name.encode! 'utf-8' 18 end 19 ext = File.extname(entry.name) #拡張子を取得 20 # 隠しファイルやゴミファイルは飛ばす 21 next if ext.blank? || File.basename(entry.name).count(".") > 1 22 23 num += 1 24 if num > 30 then 25 break 26 end 27 28 # 一時ファイルを作る 29 Tempfile.open(["tempProductImageFile", ext]) do |t| 30 entry.extract(t.path) { true } 31 @product.send("products_image#{num}=", t) 32 end 33 end 34 end