Feature #4592
openTempfileを直接保存したい
Description
=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。
#save とか #save! とか、何がいいかは議論の余地があると思います。
=end
Updated by sakuro (Sakuro OZAWA) over 13 years ago
#close(real=false)
したあと、 #path
を使って、保存したいところに File#rename
とか、 File#link
を使うとよいと思います。
Updated by sakuro (Sakuro OZAWA) over 13 years ago
先頭が # だと丸ごと見えなくなるのか…
#close(real=false)
したあと、#path
を使って、保存したいところに File#rename
とか、 File#link
を使うとよいと思います。
Updated by mrkn (Kenta Murata) over 13 years ago
Tempfile#mv(path)
というメソッドを追加するパッチを書いてみました。
https://gist.github.com/933915
File.rename
してるので、元のファイルが無くなっちゃいますし、
元のファイルと同じファイル名のまま維持したい場合は使えなかったりします。
Updated by sakuro (Sakuro OZAWA) over 13 years ago
FileUtils
と間違えた。 rename
や link
は File
のクラスメソッドでした。
Updated by shyouhei (Shyouhei Urabe) over 13 years ago
-
closeと同時というのを諦め、closeのちょっと後でよければ、普通にmvできるのではないでしょうか。
irb(main):001:0> f = Tempfile.new('') => #<File:/tmp/20110421-7098-1bvjwc0> irb(main):002:0> f.puts("foobar") => nil irb(main):003:0> f.close; File.rename(f, "tmp.txt") => 0 irb(main):008:0> File.read("tmp.txt") => "foobar\n"
-
/tmpとRubyのカレントディレクトリが別パーティションだったら、どのみちコピーは発生するのではないでしょうか。
-
Tempfile
を保存したいというのはTempfile
の意味からして本末転倒なのではないでしょうか。
といった感想を抱きました。
Updated by xibbar (Takeyuki FUJIOKA) over 13 years ago
卜部さんの言うとおりなのですが、ユースケースを書きますと、
Railsもcgi.rbも巨大なファイルをアップロードしたときは
tempfileにファイルを保存します。
これを保存したいとなったときに、
tempfileから読みだして、別ファイルをオープンして
書きこむという手間とメモリが必要なので、
tempfileに入っているんだから、そのままリネームでもして
保存出来ればいいのになと思ったのでした。
ちなみに卜部さんのやり方ももちろんOKですが、
私的にはHTTP Requestをまたいで使いたいので、
tempfileを消えないようにだけするという対応でも
OKなのでした。tempfile名をセッションにでも入れて、
次のリクエストでまた開くということをやりたかったです。
Updated by mame (Yusuke Endoh) over 12 years ago
- Description updated (diff)
- Status changed from Open to Assigned
- Assignee set to mame (Yusuke Endoh)
Updated by akr (Akira Tanaka) over 12 years ago
remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。
Updated by ko1 (Koichi Sasada) over 12 years ago
(2012/03/25 15:33), akr (Akira Tanaka) wrote:
remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。
mv なり hardlink などして,File を返すインターフェースとかだと良かった
りしないでしょかね.「消されない」Tempfile ってのに違和感がありまして.
Tempfile#mv(filepath) #=> File とか,cp でもいいか.
--
// SASADA Koichi at atdot dot net
Updated by mame (Yusuke Endoh) over 12 years ago
どういう意味でこのチケットを自分にアサインしたか忘れてしまったのですが。
shyouhei (Shyouhei Urabe) wrote:
closeと同時というのを諦め、closeのちょっと後でよければ、普通にmvできるのではないでしょうか。
irb(main):001:0> f = Tempfile.new('') => #<File:/tmp/20110421-7098-1bvjwc0> irb(main):002:0> f.puts("foobar") => nil irb(main):003:0> f.close; File.rename(f, "tmp.txt") => 0 irb(main):008:0> File.read("tmp.txt") => "foobar\n"
これは、GC タイミングによっては失敗しますよね。(f.close の直後で GC)
また、rename 後に元のファイル名と同じファイルを作ったら、この tempfile が
GC される際に消されてしまう危険があると思います。
よって、workaround としては推奨しかねるものだと思います。
- /tmpとRubyのカレントディレクトリが別パーティションだったら、どのみちコピーは発生するのではないでしょうか。
気にするなら、Tempfile 生成ディレクトリを自分で指定すればいいと思います。
- Tempfileを保存したいというのはTempfileの意味からして本末転倒なのではないでしょうか。
これは個人の感覚の問題だと思いますが、「temporary だけど、うまく行けば
永続化するつもり」というのは私はいいかなあと思いました。
akr (Akira Tanaka) wrote:
remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。
Tempfile#persist とか、秋葉原の開発者会議で出た案でしたっけ。
--
Yusuke Endoh mame@tsg.ne.jp
Updated by mame (Yusuke Endoh) over 12 years ago
- Assignee changed from mame (Yusuke Endoh) to matz (Yukihiro Matsumoto)
mame (Yusuke Endoh) wrote:
どういう意味でこのチケットを自分にアサインしたか忘れてしまったのですが。
思い出しました。開発者会議で出た内容をまとめて matz に振るのでした。
しかし開発者会議で出た内容を正確に覚えてないんですが、
- ユースケースは理解できる
- 卜部さんの workaround は推奨されない
- 良い API・名前はなんだろう
くらいだったと思います。間違ってたら正してください > 参加者
matz が直接判断しなくても、tempfile.rb のメンテナになってくれる人が
いれば判断できると思います。
まあメンテナになるのに matz の承認が必要ですが。
あと訂正。
これは、GC タイミングによっては失敗しますよね。(f.close の直後で GC)
これは間違いでした。f の参照が残っているので GC されることはありません。
でも race condition の問題はあるので、やはり推奨はされない、という話
だったと思います。
--
Yusuke Endoh mame@tsg.ne.jp
Updated by ko1 (Koichi Sasada) over 12 years ago
(2012/04/02 21:50), mame (Yusuke Endoh) wrote:
くらいだったと思います。間違ってたら正してください > 参加者
間違ってないですが,個人的には Tempfile インスタンスのまま消えないのは
不思議なので,Tempfile#xxx #=> File みたいなメソッド xxx があるといいん
じゃないかなぁ,と.って,ruby-dev:45436 に書いてるじゃん.
--
// SASADA Koichi at atdot dot net
Updated by mame (Yusuke Endoh) about 12 years ago
- Target version set to 2.6
Updated by xibbar (Takeyuki FUJIOKA) over 11 years ago
Updated by Glass_saga (Masaki Matsushita) over 6 years ago
- Related to Feature #13743: Support linking of files opened with O_TMPFILE added
Updated by Glass_saga (Masaki Matsushita) over 6 years ago
- Related to deleted (Feature #13743: Support linking of files opened with O_TMPFILE)