[Ruby 1.9 - Feature #4592][Open] Tempfileを直接保存したい

Issue #4592 has been reported by Takeyuki F…


Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by Sakuro OZAWA.

#close(real=false)したあと、#path を使って、保存したいところに File#rename とか、File#link
を使うとよいと思います。


Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by Sakuro OZAWA.

先頭が # だと丸ごと見えなくなるのか…

((%#close(real=false)%))したあと、#path を使って、保存したいところに File#rename
とか、File#link を使うとよいと思います。


Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by Sakuro OZAWA.

FileUtilsと間違えた。renameやlinkはFileのクラスメソッドでした。


Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by Shyouhei U…

  • 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の意味からして本末転倒なのではないでしょうか。

といった感想を抱きました。

Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by Takeyuki F…

卜部さんの言うとおりなのですが、ユースケースを書きますと、
Railsもcgi.rbも巨大なファイルをアップロードしたときは
tempfileにファイルを保存します。
これを保存したいとなったときに、
tempfileから読みだして、別ファイルをオープンして
書きこむという手間とメモリが必要なので、
tempfileに入っているんだから、そのままリネームでもして
保存出来ればいいのになと思ったのでした。

ちなみに卜部さんのやり方ももちろんOKですが、
私的にはHTTP Requestをまたいで使いたいので、
tempfileを消えないようにだけするという対応でも
OKなのでした。tempfile名をセッションにでも入れて、
次のリクエストでまた開くということをやりたかったです。

Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

Issue #4592 has been updated by mame (Yusuke E.).

Description updated
Status changed from Open to Assigned
Assignee set to mame (Yusuke E.)


Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-25116

Author: xibbar (Takeyuki F.)
Status: Assigned
Priority: Normal
Assignee: mame (Yusuke E.)
Category: lib
Target version:

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

Issue #4592 has been updated by Kenta M…

Tempfile#mv(path) というメソッドを追加するパッチを書いてみました。
https://gist.github.com/933915

File.rename してるので、元のファイルが無くなっちゃいますし、
元のファイルと同じファイル名のまま維持したい場合は使えなかったりします。


Feature #4592: Tempfileを直接保存したい
http://redmine.ruby-lang.org/issues/4592

Author: Takeyuki F.
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:

Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。

(2012/03/25 15:33), akr (Akira T.) wrote:

remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。

mv なり hardlink などして,File を返すインターフェースとかだと良かった
りしないでしょかね.「消されない」Tempfile ってのに違和感がありまして.

Tempfile#mv(filepath) #=> File とか,cp でもいいか.

Issue #4592 has been updated by akr (Akira T.).

remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。

Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-25117

Author: xibbar (Takeyuki F.)
Status: Assigned
Priority: Normal
Assignee: mame (Yusuke E.)
Category: lib
Target version:

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

Issue #4592 has been updated by mame (Yusuke E.).

どういう意味でこのチケットを自分にアサインしたか忘れてしまったのですが。

shyouhei (Shyouhei U.) 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 T.) wrote:

remove_finalizer とか、save とかよりももうちょっと長い名前がいいんじゃないかなぁ、と思います。

Tempfile#persist とか、秋葉原の開発者会議で出た案でしたっけ。


Yusuke E. [email protected]

Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-25527

Author: xibbar (Takeyuki F.)
Status: Assigned
Priority: Normal
Assignee: mame (Yusuke E.)
Category: lib
Target version:

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

Issue #4592 has been updated by mame (Yusuke E.).

Assignee changed from mame (Yusuke E.) to matz (Yukihiro M.)

mame (Yusuke E.) wrote:

どういう意味でこのチケットを自分にアサインしたか忘れてしまったのですが。

思い出しました。開発者会議で出た内容をまとめて matz に振るのでした。
しかし開発者会議で出た内容を正確に覚えてないんですが、

  • ユースケースは理解できる
  • 卜部さんの workaround は推奨されない
  • 良い API・名前はなんだろう

くらいだったと思います。間違ってたら正してください > 参加者

matz が直接判断しなくても、tempfile.rb のメンテナになってくれる人が
いれば判断できると思います。
まあメンテナになるのに matz の承認が必要ですが。

あと訂正。

これは、GC タイミングによっては失敗しますよね。(f.close の直後で GC)

これは間違いでした。f の参照が残っているので GC されることはありません。
でも race condition の問題はあるので、やはり推奨はされない、という話
だったと思います。


Yusuke E. [email protected]

Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-25598

Author: xibbar (Takeyuki F.)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro M.)
Category: lib
Target version:

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

Issue #4592 has been updated by mame (Yusuke E.).

Target version set to next minor


Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-33282

Author: xibbar (Takeyuki F.)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro M.)
Category: lib
Target version: next minor

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

Issue #4592 has been updated by xibbar (Takeyuki FUJIOKA).

Tempfile#to_file!(path)

とか?

自分の提起チケットなので反応してみました。

いろいろあった結果、担当がMatzになっていますね。


Feature #4592: Tempfileを直接保存したい
https://bugs.ruby-lang.org/issues/4592#change-39136

Author: xibbar (Takeyuki FUJIOKA)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro M.)
Category: lib
Target version: next minor

=begin
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、
ファイルが消えてしまいます。
Tempfileのデータを保存するために
一旦読みだして、書き込み用に別ファイルを開いて、
そこに書きこまなければいけません。
これが小さいファイルだったらいいのですが、
大きいファイルになると、
Tempfile#save みたいなメソッドを用意して、
closeと同時に保存ができると、
読みだして書きこむという無駄をなくすことができます。
10MB程度だったらいいのですが、500MとかのTempfileだと
かなり有効なメソッドだと思います。

#save とか #save! とか、何がいいかは議論の余地があると思います。
=end

(2012/04/02 21:50), mame (Yusuke E.) wrote:

くらいだったと思います。間違ってたら正してください > 参加者

間違ってないですが,個人的には Tempfile インスタンスのまま消えないのは
不思議なので,Tempfile#xxx #=> File みたいなメソッド xxx があるといいん
じゃないかなぁ,と.って,[ruby-dev:45436] に書いてるじゃん.