web-dev-qa-db-fra.com

Est-il sûr de ne pas fermer un scanner Java, à condition que je ferme le sous-jacent lisible?

Si j'ai une méthode qui prend un lecteur et que je veux opérer sur le lecteur avec un scanner comme ça:

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

Est-il sûr de ne pas fermer scanner? La documentation indique qu'il "ferme ce scanner" et parle ensuite de la fermeture du lisible sous-jacent. Supposons que je ne veuille pas fermer le fichier lisible et que je souhaite que l'appelant ferme reader lorsqu'il est prêt. Est-il sûr de ne pas fermer scanner ici?

32
Anthony

Cela dépend de ce contre quoi vous voulez vous protéger.

  • Si vous essayez simplement de vous assurer que le flux sous-jacent est fermé, alors l'une ou l'autre approche convient.

  • Si vous souhaitez également que Scanner soit marqué comme fermé (de sorte que toutes les opérations suivantes sur l'objet échouent immédiatement), vous devez appeler Scanner.close().

Il s'agit d'un principe général; c'est-à-dire qu'il s'applique également à divers types de flux qui effectuent la mise en mémoire tampon en mémoire, d'une manière ou d'une autre.

23
Stephen C

Puisque j'ai déjà le code source ouvert :-) ...

La méthode close() vérifie si le Readable sous-jacent implémente également l'interface Closeable, et s'il le fait, il le ferme. Dans votre situation, vous dites que ce n'est pas un problème car il sera fermé plus tard.

Mais la méthode close() définit également des indicateurs internes indiquant que le Scanner (et le Readable sous-jacent) sont fermés. De nombreuses méthodes publiques vérifient d'abord si le Scanner a été fermé. Donc, le danger ici serait que votre Readable sous-jacent a été fermé, mais d'autres appels à Scanner ne lancent pas immédiatement un IllegalStateException, et échouent à la place dans certains autres comme ils procèdent.

Si vous pouvez vous assurer que rien d'autre n'a de descripteur sur l'instance Scanner en question, et que vous n'essaierez pas d'appeler d'autres méthodes dessus, vous pouvez être d'accord.

La méthode close() annule également sa référence au Readable, donc si cela ne se produit pas, le Scanner ne récupérera pas les ordures dès qu'il l'aurait fait vous avez appelé close().

J'appellerais Scanner.close() si possible.

9
David

Je devais également fermer le Scanner et garder le flux sous-jacent ouvert pour continuer le travail. J'ai créé une classe qui étend BufferedInputStream et remplace la méthode close() par un corps vide. Cette classe j'ai alimenté le constructeur du Scanner. De cette façon, vous pouvez appeler scanner.close() sans fermer le flux. Vous devez cependant conserver une référence au BufferedInputStream d'origine, mais c'est évident.

1
Chris

Eh bien, si vous avez des cours Caller et Reader. L'appelant ne doit pas connaître l'implémentation de Reader. Dans la méthode suivante du lecteur:

while scanner has object
   read them ( one object per method's call) 
when objects are done
   close the reader. 

Il s'agit d'une sorte de modèle d'itérateur.

0
StKiller