質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Q&A

解決済

1回答

3023閲覧

圧縮ファイルを解凍したものをローカルなどに一時ファイルとして保存せずに中身を参照したい

nomura

総合スコア116

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

1グッド

0クリップ

投稿2018/09/11 03:19

編集2018/09/11 03:23

やりたいこと

Linuxコマンドでいうと、

unzip -c target.zip | cat

を実行した結果を配列に格納していくイメージです。

pythonでは出来るんですが、rubyでも同じ事は出来るはずだと思っています。
参考

考えたこと

require zip path = 'target.zip' Zip::File.open(path) do |zip| zip.each do |file| # このやり方が合っているか分からない file.get_input_stream do |contents| # ここでファイルの内容を取得できる方法があるのでは? end end end

ここでのrequire zipはrubyzipを使っていますが、こだわりはありません。

期待する結果

echo AB\nCD\nEF\n... >test1.txt echo 12\n34\n56\n... >test2.txt zip target.zip test1.txt test2.txt

で作成されていた場合、

require zip # zipのファイルを配列arrayに格納 p array[0] # AB # CD # EF # ... p array[1] # 12 # 34 # 56 # ...

改行部分は\n等で表示される分には問題ありません。

避けたいこと

zipを解凍したファイルをディスクにファイルを保存するのは避けたいです。
たとえばzipをtmpなりに解凍して、tmpディレクトリ以下のファイルをglobして何かしらの処理を行った後、tmpディレクトリごと削除する、というような方法です。
現在exec.rbを実行しているかどうかをプロセスIDや.lockファイルなどを作って処理待ちの判別をさせるような処理も避けたいと考えています。

運用ケース例

  • 20180911.zipの中身と20180910.zipの中身を比較すると、ファイル名が一致している
  • ファイル内から20180911などの日付を判定できる仕組みが存在しており、これらを使用してDBなどに登録している

rubyを諦めてpythonでやれば出来るんですが、今回はrubyで出来るかどうかが知りたいです。

※ 上記の考えたことのソースはなんか出来そうな雰囲気で書いていますのでやり方が間違っている可能性はありえます。

追記

Rubyやgemなどのバージョンについては特に意識していませんが、
それぞれ2.5.0, 2.7.3を使用しています。

yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

rubyzipのREADMEに書かれている、Reading a Zip fileのやり方でOKです。

例えばこんな感じです。

ruby

1require 'zip' 2 3Zip::File.open("target.zip") do |zip_file| 4 entries = zip_file.map do |entry| 5 entry.get_input_stream.read 6 end 7 8 p entries 9end

ちなみに、entry.get_input_streamで取得できるオブジェクトは、Zip::InputStreamのようです。

投稿2018/09/11 04:03

編集2018/09/11 04:08
ikemo

総合スコア332

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nomura

2018/11/02 07:47

ご回答ありがとうございます、今手元で試してみたら仰る通りでした。 なぜzip_file.eachではダメで.mapなのか、entry.get_input_stream.readがなぜ必要なのか、ループ中にp entryで期待した結果が得られないのはなぜか、などなど分からない事が多いのですが、ソースコードを見つつ、pythonとruby自体のふるまいの違いも気にしてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問