2016-10-05 1 views
4

Scalaアプリケーションでは、java nio try-with-resource構文を使用してファイルから行を読み込もうとしています。Javaのtry-with-resourceがscalaで動作しない

Scalaのバージョン2.11.8
Javaバージョン1.8

try(Stream<String> stream = Files.lines(Paths.get("somefile.txt"))){ 
    stream.forEach(System.out::println); // will do business process here 
}catch (IOException e) { 
    e.printStackTrace(); // will handle failure case here 
} 

しかし、コンパイラが見つから
◾notのようなエラーがスローされます:キャッチすることなく、または最後にしようと◾A値ストリーム
は、そのを置くと等価ですブロック内のボディ。例外は処理されません。

問題が何かわかりません。 Java NIOを初めて使用しているので、どんな助けでも大歓迎です。

+0

何も間違っては、Javaコード –

+0

ではありません[この](HTTPS:/ /www.phdata。io/try-with-scala /)は適用できますか? –

+4

ScalaとJavaは異なる言語です。 ScalaプログラムでJava構文がうまくコンパイルされることは期待できません。関連:http://stackoverflow.com/questions/25634455/simple-scala-pattern-for-using-try-with-resources-automatic-resource-manageme、http://stackoverflow.com/questions/2207425/what- scalaのための自動リソース管理の代替手段 –

答えて

13

直接試す-と資源Scalaで構築javasのためにサポートしていますが、あなたはとても簡単融資パターンを適用することで、独自のサポートを構築することができていないがあります:

import java.lang.AutoCloseable 
import java.nio.file.{Files, Paths} 
import java.util.Optional 

def autoClose[A <: AutoCloseable,B](
     closeable: A)(fun: (A) ⇒ B): B = { 
    try { 
     fun(closeable) 
    } finally { 
     closeable.close() 
    } 
} 

これは、再利用可能なメソッドを定義して、ということJavaのtry-with-resource構文によく似ています。それは2つのパラメータを取って動作します。 First isはAutoclosableインスタンスのサブクラスをとり、2つ目はパラメータと同じAutoclosable型をとる関数をとります。関数パラメータの戻り値の型は、メソッドの戻り値の型として使用されます。次に、このメソッドはtry内で関数を実行し、finallyブロックのautoclosebleを閉じます。

あなたはストリーム上findAny()の結果を得るためにここ(このように使用し、それを使用することができます。場合

val result: Optional[String] = autoClose(Files.lines(Paths.get("somefile.txt"))) { stream ⇒ 
    stream.findAny() 
} 

あなたの希望をキャッチ例外を行うために、あなたは2の選択肢があります。

  1. 。stream.findAny()の呼び出しの周り

  2. をtry/catchブロックを追加したり、オートクローズ方式でtryブロックにcatchブロックを追加します。ロジック場合にのみ、行われるべきであることに注意してくださいcatchブロックの内側は、autoCloseが呼び出されるすべての場所から使用できます。

    あなたはすでに答えの一つに言及している
+0

ありがとう、私はこのソリューションを実装しています。 –

+2

あなたは@ anders-kreinøeがクレジットを得るために解決策を受け入れるべきです。 – Phasmid

1

が近づい:

def autoClose[A <: AutoCloseable, B](resource: A)(code: A ⇒ B): B = { 
    try 
     code(resource) 
    finally 
     resource.close() 
    } 

をしかし、私は次のようにはるかにエレガントだと思う:

def autoClose[A <: AutoCloseable, B](resource: A)(code: A ⇒ B): Try[B] = { 
    val tryResult = Try {code(resource)} 
    resource.close() 
    tryResult 
    } 

最後のものでは私見それは簡単です制御フローを処理する。

0

また、ChoppyのTryCloseモナドを使用すると、for-comprehensionでScalaのTryと同様に構成可能な方法でこれを行うことができます。

val ds = new JdbcDataSource() 
val output = for { 
    conn <- TryClose(ds.getConnection()) 
    ps <- TryClose(conn.prepareStatement("select * from MyTable")) 
    rs <- TryClose.wrap(ps.executeQuery()) 
} yield wrap(extractResult(rs)) 

は、ここでは、あなたのストリームでそれを行うだろう方法は次のとおりです。ここ

val output = for { 
    stream <- TryClose(Files.lines(Paths.get("somefile.txt"))) 
} yield wrap(stream.findAny()) 

さらに詳しい情報: https://github.com/choppythelumberjack/tryclose

関連する問題