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