2012-01-05 15 views
0

私はthis answerによってプロンプトされたscala-armライブラリを見ていて、ほとんどのコンテキストでリソースを管理するのに適しています。Scalaでクローズ可能なリソースの引き渡しを管理する最善の方法は何ですか?

しかし、最初の一見では、リソースを別のリソースに「引き渡す」ことを処理していないような状況があります。 I/Oを扱うとき、これが頻繁に来る:

for (fin <- managed(new FileInputStream(file)); 
    // almost what we want, except see below 
    gzip <- managed(new GZIPInputStream(fin)); 
    src <- managed(Source.fromInputStream(gzip))) { 
    /* some fancy code */ 
} 

が今、問題はこれです:gzipが正常に作成されている場合は、それフィンを閉じるための責任がある、とフィンはすべきではありません閉鎖しました(更新:これは正しくありません - ダブルクローズは問題​​ありません;回答を参照)。しかし、代替、:

for (src <- managed(Source.fromInputStream(
       new GZIPInputStream(new FileInputStream(file))))) { 
    /* some fancy code */ 
} 

はかなり正確ではありません - GZIPInputStreamコンストラクタで(確かにそう)にエラーが発生した場合、FileInputStreamは閉じられません。同上はfromInputStreamです。

scala-arm(または他のパッケージ)は、このクリーンアップを安全に取り扱うための機能を提供していますが、まだ見つけられていませんか?

答えて

3

数分以上見て、本当に問題ではないことがわかりました。 java.io.Closeableは、すでに閉じられているリソースを操作していないことを示します。したがって、すべてをmanagedにラップしてダブルクローズすることは安全です。したがって、最初のコード例は正しいです。

1

私にとって最良のアプローチは、機能的な世界で資金を得ているiteratee、enumeratorおよびenumerateeという概念を使用することです。

あなたが興味を持っているのは、非常に優れた実装を持つScalazライブラリです。

これらの概念は、コンソリエーターがコンデミングを完了した時を知っているソースのイテレーターと、逆もまた同様であることを知るために使用されます。ソースを知っていることを条件にすることは何も提供していません。ここで

EDIT

はiterateeはのためにあるものについて非常に明確postです。あなたの問題について話しているモチベーションのパラメータを参照してください...何がうまくいったのか、間違っていても、適切な時にいつでもリソースを閉じる

+0

私はあなたが何を意味しているのか、特に "提供する "。私の問題は、私が終わったときに閉じることではなかった。それは私が入力チェーンをsucccessfully設定することができなかったとしても、ファイルが閉じられていることを確認することでした。 –

+0

実際、このiteratee、enumeratorおよびenumerateeは、両方の(そしてその他の)ケースを解決するために存在します。ソースが生産を終了したとき(あなたが気にしないもの)とコンシューマーが完了したとき(そして実際に失敗したときに終了したとき)。私は非常に役に立つポストを追加するつもりです。それはその話題(**はあなたの懸念に対する解決策です**)にあなたを照らします。 –

+0

ありがとう - そのポストは大いに役立ちます。興味深い解決策のように見えますが、すべてがIterateesの周りに構築されていることを前提としています。しかし、Javaの標準フィルタリングされたストリームとリーダーを使用することに直接適用されるようには見えませんが、Iterateesは何も知らないのです。 –

関連する問題