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?
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.
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.
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.
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.