Каков наилучший способ управления передачей закрытых ресурсов в Scala? - PullRequest
0 голосов
/ 05 января 2012

Я смотрю на библиотеку scala-arm , подсказанную этим ответом , и она отлично подходит для управления ресурсами в большинстве контекстов.

Есть однаконтекст, тем не менее, на первый взгляд кажется, что он не справляется: это «передача» ресурса другому ресурсу.Это часто возникает при работе с 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 успешно создан, то it отвечает за закрытие fin и fin не должны закрываться ( update : это не совсем верно - двойное закрытие - это хорошо; см. принятый ответ).Альтернатива, однако:

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

не совсем корректна - если в конструкторе GZIPInputStream есть (предположительно маловероятная) ошибка, FileInputStream не закрывается.То же самое для fromInputStream.

Предоставляет ли scala-arm (или какую-либо другую упаковку) средство для безопасной обработки этой очистки, которую я еще не нашел?

Ответы [ 2 ]

3 голосов
/ 05 января 2012

Сделал еще несколько минут поиска и обнаружил, что это действительно не имеет значения.java.io.Closeable указывает, что close() использование уже закрытого ресурса запрещено.Так что можно безопасно завернуть все в managed и позволить ему дважды закрыться.Следовательно, первый пример кода верен.

1 голос
/ 06 января 2012

Лучший подход для меня - это использовать понятие итератора, перечислителя и перечислителя, которое имеет свое происхождение в функциональном мире.

Вас может заинтересовать библиотека Scalaz, которая имеет очень хорошую реализацию.

В некоторых словах эти понятия используются для того, чтобы итератор в источнике знал, когда завершилось потребление, а также наоборот. Имея минусы, зная источник, ничего не может предоставить.

EDIT

Вот очень ясный пост о том, для чего итерируемый. Посмотрите параметр мотивации, который говорит о вашей проблеме ... закрытие ресурсов, когда что-то пошло хорошо или неправильно, но в нужное время

...