#java #java.util.scanner
#java #java.util.scanner
Вопрос:
Если у меня есть метод, который использует reader, и я хочу работать с reader с помощью сканера следующим образом:
Scanner scanner = new Scanner(reader);
while(scanner.hasNext()) {
//blah blah blah
}
Безопасно ли не закрывать scanner
? В документации говорится, что он «закрывает этот сканер», а затем говорится о закрытии базового readable. Предположим, я не хочу закрывать readable и вместо этого хочу, чтобы вызывающий объект закрылся reader
, когда будет готов. Безопасно ли не закрывать scanner
здесь?
Ответ №1:
Это зависит от того, от чего вы хотите быть в безопасности.
-
Если вы просто пытаетесь убедиться, что базовый поток закрыт, то подойдет любой подход.
-
Если вы также хотите, чтобы
Scanner
объект был помечен как закрытый (чтобы все последующие операции с объектом немедленно завершились неудачей), тогда вам следует вызватьScanner.close()
.
Это общий принцип; т. Е. он также применим к различным типам потоков, которые так или иначе выполняют буферизацию в памяти.
Комментарии:
1. Этот ответ соответствует контракту, как определено в документации .
Ответ №2:
Поскольку у меня уже открыт исходный код 🙂 …
close()
Метод проверяет, Readable
также реализует Closeable
ли базовый интерфейс, и если это так, он закрывает его. В вашей ситуации вы говорите, что это не проблема, потому что он будет закрыт позже.
Но close()
метод также устанавливает некоторые внутренние флаги, указывающие, что Scanner
(и базовый Readable
) закрыты. Многие общедоступные методы сначала проверяют, был ли Scanner
закрыт. Таким образом, опасность здесь может заключаться в том, что, возможно, ваш базовый Readable
был закрыт, но дальнейшие вызовы Scanner
не выдают an немедленно IllegalStateException
, а вместо этого завершаются сбоем каким-либо другим способом по мере продолжения.
Если вы можете убедиться, что ничто другое не имеет дескриптора для Scanner
рассматриваемого экземпляра, и не будет пытаться вызывать для него какие-либо дополнительные методы, тогда все может быть в порядке.
close()
Метод также обнуляет свою ссылку на Readable
, поэтому, если этого не произойдет, Scanner
мусор не будет собран, как только вы бы вызвали его close()
.
Я бы позвонил Scanner.close()
, если это возможно.
Ответ №3:
Мне также нужно было закрыть Scanner
и оставить базовый поток открытым для дальнейшей работы. Что я сделал, так это создал класс, который расширяет BufferedInputStream
и переопределяет close()
метод с пустым телом. Этот класс я ввел в конструктор Scanner
. Таким образом, вы можете вызывать scanner.close()
, не закрывая поток. Вам нужно сохранить ссылку на оригинал BufferedInputStream
, хотя, но это очевидно.
Ответ №4:
Хорошо, если у вас есть класс Caller и Reader. Вызывающий не должен знать о реализации Reader. В следующем методе reader:
while scanner has object
read them ( one object per method's call)
when objects are done
close the reader.
Это своего рода шаблон итератора.