Подтвердить что ты не робот

Безопасно ли не закрывать сканер Java, если я закрываю базовый читаемый?

Если у меня есть метод, который берет читателя, и я хочу работать с читателем со Сканером, например:

Scanner scanner = new Scanner(reader);
while(scanner.hasNext()) {
    //blah blah blah
}

Безопасно ли закрывать scanner? Документация говорит, что он "закрывает этот сканер", а затем говорит о закрытии базового читаемого. Предположим, я не хочу закрывать чтение и вместо этого хочу, чтобы вызывающий абонент закрывал reader, когда был готов. Безопасно ли здесь закрывать scanner?

4b9b3361

Ответ 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. 

Это своего рода шаблон итератора.