[英]Are Iteratees safe for managing resources?
假設我正在從InputStream
中讀取。
我通常怎么做:
val inputStream = ...
try {
doStuff(inputStream)
} finally {
inputStream.close()
}
無論doStuff
是否拋出異常,我們都會關閉InputStream
。
我將如何使用iteratees:
val inputStream ...
Enumerator.fromStream(inputStream)(Iteratee.foreach(doStuff))
是否會關閉InputStream
(即使doStuff
引發異常)?
一點測試:
val inputStream = new InputStream() { // returns 10, 9, ... 0, -1
private var i = 10
def read() = {
i = math.max(0, i) - 1
i
}
override def close() = println("closed") // looking for this
}
Enumerator.fromStream(inputStream)(Iteratee.foreach(a => 1 / 0)).onComplete(println)
我們只看到:
Failure(java.lang.ArithmeticException: / by zero)
這條小溪從未關閉過。 更換1 / 0
與1 / 1
你會看到流關閉。
當然,我可以維護對原始流的引用並在發生故障時關閉它,但AFAIK使用iteratees的想法是創建可組合迭代而不必這樣做。
這是預期的行為嗎?
有沒有辦法使用迭代,所以資源總是正確配置?
Iteratees專為安全資源管理而設計。 請參閱Iteratee IO的第一句:安全,實用,聲明性的輸入處理 :
Iteratee IO是一種增量輸入處理方式,具有精確的資源控制。
我們的想法是,當您的資源僅通過迭代訪問時,資源擁有代碼可以確切地告知迭代何時完成資源並立即關閉它。 另一方面,當手動管理迭代時(與傳統的InputStream
),資源的用戶負責關閉它。 這可能導致泄漏。
說,Play 2.1中有一個錯誤,其中fromStream
沒有管理其底層InputStream
的關閉! 這個錯誤在Play 2.2中得到修復。
您可以通過使用onDoneEnumerating
在iteratee完成時關閉資源來查看fromStream
代碼以查看Enumerator
是如何修復的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.