フォームで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までに入っているファイルは複数あります。
def create
@product = Product.new(product_params)
p "1111111111111111111111111111111"
p product_params[:zip]
p "1111111111111111111111111111111"
Zip.unicode_names = true
Zip.force_entry_names_encoding = 'UTF-8'
zipfile = product_params[:zip]
Zip::File.open(zipfile.path) do |zip|
num = 0
zip.each do |entry|
entry.name.force_encoding('UTF-8')
entry_name = entry.name.encode("UTF-16BE", "UTF-8", :invalid => :replace, :undef => :replace, :replace => '?').encode("UTF-8")
p "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
p entry_name
p "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
ext = File.extname(entry_name) #拡張子を取得
# 隠しファイルやゴミファイルは飛ばす
next if ext.blank? || File.basename(entry_name).count(".") > 1
num += 1
if num > 30 then
break
end
# 一時ファイルを作る
Tempfile.open(["tempProductImageFile", ext]) do |t|
entry.extract(t.path) { true }
@product.send("products_image#{num}=", t)
end
end
end
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のコードを追加しましたが、問題点に変化がありません。
Zip::File.open(zipfile.path) do |zip|
num = 0
zip.each do |entry|
unless entry.name.valid_encoding?
entry.name.force_encoding case NKF.guess(entry.name)
when NKF::EUC then 'euc-jp'
when NKF::SJIS then 'cp932'
when NKF::UTF8 then 'utf-8'
when NKF::UTF16 then 'utf-16'
when Encoding::EUCJP_MS then Encoding::EUCJP_MS
when Encoding::CP51932 then Encoding::CP51932
when Encoding::WINDOWS_31J then Encoding::WINDOWS_31J
else
# JISコードもしくは不明
raise "文字コードが想定外です"
end
entry.name.encode! 'utf-8'
end
ext = File.extname(entry.name) #拡張子を取得
# 隠しファイルやゴミファイルは飛ばす
next if ext.blank? || File.basename(entry.name).count(".") > 1
num += 1
if num > 30 then
break
end
# 一時ファイルを作る
Tempfile.open(["tempProductImageFile", ext]) do |t|
entry.extract(t.path) { true }
@product.send("products_image#{num}=", t)
end
end
end
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
Zip.unicode_names=true
を設定することで解決できるという記事がありました。
https://tmtms.hatenablog.com/entry/2017/04/10/rubyzip
検証してないので環境によってできないものがあるかもしれません。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
非常に面倒くさいことになってる予感がします・・・
Zip.unicode_names = true
は、(主に)圧縮時のオプションです
Zip.force_entry_names_encoding = 'UTF-8'
は
entry.name.force_encoding('UTF-8')
と全く同じ効果しかありません。
なので、unpack時にutf-8でない場合は自分で文字コードを推定する必要があります。
NKF.guess
やcharlock_holmesを用いる方法があります。
# NKFを用いた場合
require 'nkf'
unless entry.name.valid_encoding?
entry.name.force_encoding case NKF.guess(entry.name)
when NKF::EUC then 'euc-jp'
when NKF::SJIS then 'cp932'
when NKF::UTF8 then 'utf-8'
when NKF::UTF16 then 'utf-16'
when Encoding::EUCJP_MS then Encoding::EUCJP_MS
when Encoding::CP51932 then Encoding::CP51932
when Encoding::WINDOWS_31J then Encoding::WINDOWS_31J
else
# JISコードもしくは不明
raise "文字コードが想定外です"
end
entry.name.encode! 'utf-8'
end
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
dice142
2018/12/21 19:10
動作環境を追記していただけますか?
s_diff
2018/12/21 19:18
わかりました。
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin17]
Rails 4.2.6
rubyzip (1.2.2)
以上が動作環境です。
dice142
2018/12/21 19:23
文字コードが関係しているのでOS情報もお願いします。
また、質問文に追記して頂けた方が他の方も見やすいです。
s_diff
2018/12/21 19:24
ご指摘ありがとうございます。