質問を見ていただいて有難うございます。
長文になりますが、宜しくお願いいたします。
最終的な質問をまとめると、
『file descriptorをSTDOUTに切り替えるにはどうしたら良いですか?』
になるかと思いますが、目的から経緯についても以下に記します。
zipファイルを標準出力に書き出したいです。
プログラム上で作り出したzipファイル形式のデータを、
ディスクに書き出すのではなく、標準出力に書き出したいのです。
zipファイルをレスポンスするcgiを作りたいからです。
zipファイルを生成するライブラリは、探したところ
・rubyzip
・zipruby
というのがありました。
ziprubyには、Zip::Archive.open_bufferというメソッドがあったので、
これを利用して以下の様に書いてみました。(行頭スペースは全角です)
-------------------------------------------------------------
#!/usr/local/bin/ruby
require 'cgi'
require 'rubygems'
require 'zipruby'
body=''
Zip::Archive.open_buffer(body, Zip::CREATE) do |ar|
ar.add_buffer('first_entry.txt','Hello world!')
ar.add_dir('adir')
ar.add_buffer('adir/first_entry.txt','Hello again!')
end
CGI.new().out({
'status'=>'OK',
'type'=>'application/zip',
'Content-Disposition'=>'attachment; filename="hoge.zip"'
}){body}
-------------------------------------------------------------
とりあえずは、これで目的を達成できたのですが、
巨大なzipファイル生成すると、クライアント(ブラウザ)がタイムアウトしてしまいます。
そこで、CGI.new().outを使うのをやめて、STDOUTに直接、”ストリーム”に書き出そうと思います。(Chunkで)
rubyzipには、Zip::ZipOutputStream::open(ファイル名)というのがあります。
これをファイルではなく、STDOUTへ出力するように改造を試みました。
zip.rbというソースファイルを見ると、
@outputStream = File.new(fileName, "wb")
という部分があるので、この@outputStreamをSTDOUTに変えてしまえばよいと考え、
以下の様に描いてみました。
(標準出力に書き出す部分のみです。)
-------------------------------------------------------------
require 'zip/zip'
module ZipKai
include Zip
class ZipOutputStreamKai < ZipOutputStream
def initialize(fileName)
super(fileName)
@fileName = fileName
#@outputStream = File.new(fileName, "wb")
@outputStream = IO.new(1, "wb")
end
end
end
ZipKai::ZipOutputStreamKai::open("my.zip") { |io|
io.put_next_entry("first_entry.txt")
io.write "Hello world!"
io.put_next_entry("adir/first_entry.txt")
io.write "Hello again!"
}
-------------------------------------------------------------
実行してみると、以下エラーがでました。
C:/ruby/lib/ruby/gems/1.8/gems/rubyzip-0.9.1/lib/zip/zip.rb:1008:in `tell': Bad
file descriptor (Errno::EBADF)
ここで、質問です。
file descriptor(@outputStream)をSTDOUTに切り替えるにはどうしたら良いでしょうか?
※そもそも、他にもっと良い方法があるよといったご回答でもOKです。
ご指導のほど、宜しくお願いいたします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
>出来たところから、チャンクでソケットに書きたいと思いました。
出来たところからと言っても、圧縮ファイルの先頭に「圧縮後の長さ」を書かないと行けないので、ファイル単位でしか「出来」ませんよ。
つまり、細かいファイルたくさんを集めて圧縮するなら、ファイル単位で出力することで改善されますが、大きなファイル1つなら改善不可能。
いずれにせよ、やるとなると、大幅書き直しになるかと。
notnotさん、ご回答有難うございます。
細かいファイルをたくさん集めての出力なので。。。
>いずれにせよ、やるとなると、大幅書き直しになるかと。
そのようですね。
アドバイス有難うございました。
No.1
- 回答日時:
エラーメッセージからすると、ライブラリが内部でtellメソッドを使っているようですが、tellは、現在のファイル位置がファイル先頭から何バイト目かを返すメソッドで、ディスク上のファイルには使えますが、STDOUTには使えません。
いずれにせよ、処理に時間がかかってタイムアウトしているなら、出力方法をどう変えても同じだと思いますけど。圧縮に時間がかかっているのでは?
圧縮率を低く(無圧縮とか)すれば時間が短縮できると思います。
notnotさん ご回答有難うございます。
>いずれにせよ、処理に時間がかかってタイムアウトしているなら
今の方法だと、リクエストをもらってからレスポンスを開始するまでの
時間(無通信の時間)が長いので、クライアントがタイムアウトするものと思いまして。。。
出来たところから、チャンクでソケットに書きたいと思いました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- その他(セキュリティ) ZIPというファイルでパスワード付きPDFファイルが送られてきたのですが、 パスワードを入力▶︎ファ 3 2022/07/26 19:44
- Android tar.ファイルのインストールについて知りたいです 2 2022/07/23 15:34
- その他(セキュリティ) PDFファイルのパスワード設定について 1 2022/06/25 10:10
- Windows 8 メール送信、zipファイル PDFについて 回答お願いいたします。 Windows8 メールはサクラ 1 2022/05/12 17:49
- iPhone(アイフォーン) iPhone ファイル iPhoneのファイルで写真をzipに圧縮した後もう一度展開すると画質は変わ 3 2022/10/21 21:53
- アプリ アプリケーションが見つかりません 2 2022/07/13 21:07
- Windows 10 Windows ZIPファイルを解凍してフォルダ内のテキスト文書を編集して上書き保存したいのにCtr 4 2023/06/21 13:14
- ノートパソコン パソコンでZIPファイルをダウンロードしたいとき、 このような表示が出てダウンロードができないときは 2 2023/06/20 15:37
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SQLファイルの読み込み
-
C# ファイルを読み込みlistvie...
-
ファイルの文字コード
-
【ExcelVBA】300万件越えCSVか...
-
Excelマクロ 空白セルを無視し...
-
バッチ処理 特定の文字以降を...
-
Access VBA エラー2448について
-
[コンパイルエラー 修飾子が不...
-
CSVファイルの比較と結果の取得...
-
ファイル名を変数で書きこむfwr...
-
フォームのResizeイベントについて
-
EXCEL→CSV保存時のダブルクォー...
-
fortranでNAのあるデータを読み...
-
シート内容の文字列を置換してV...
-
ダブルコーテーション付きでCSV...
-
FileListBoxで出すものを絞り込...
-
【C#】 csvファイルをバイナリ...
-
eo(解凍ソフト)をバッチファイ...
-
verilog HDLについての質問です...
-
Rubyを使用してcsvファイルを処...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# ファイルを読み込みlistvie...
-
SQLファイルの読み込み
-
ファイルの読み込みデータを使...
-
【ruby】zipファイルデータをST...
-
ファイルサイズ
-
C# ファイルパスを格納した配列...
-
バッチ処理 特定の文字以降を...
-
【ExcelVBA】300万件越えCSVか...
-
ダブルコーテーション付きでCSV...
-
Excelマクロ 空白セルを無視し...
-
VBAでcsvファイルもシートもあ...
-
パイソンでテキストファイルが...
-
VBAで複数のCSVからレコードセ...
-
VBA テキストボックスを選択状...
-
fortranでNAのあるデータを読み...
-
ファイル名を変数で書きこむfwr...
-
[コンパイルエラー 修飾子が不...
-
CSVで余計な空行が入る
-
CSVデータの文字列置換
-
SQLでテキストボックスの文字を...
おすすめ情報