2010-07-12 6 views
11

Je crée une méthode Java qui accepte un seul InputStream en tant qu'argument. Pour la commodité de travailler avec un flux à base de caractères, j'enveloppe la condition InputStream au début de la mise en œuvre de la méthode comme suit:Comment éviter de fermer un InputStream passé à ma méthode que j'emballe dans les flux Reader?

public void doStuff(InputStream inStream) { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); 
    ... 
} 

Depuis le InputStream (inStream) est passé à ma méthode, je ne vouloir le fermer ... car je pense que cela devrait être la responsabilité du client appelant ma méthode (cette hypothèse est-elle correcte?). Cependant, je pense que je devrais fermer le BufferedReader que j'ai créé; mais en faisant cela, je crois qu'il fermera automatiquement tous les autres flux composés, y compris le inStream.

Quelqu'un voit-il un moyen pour moi de fermer les BufferedReader et InputStreamReader que j'ai créés sans fermer le InputStream passé à ma méthode? Peut-être qu'il y a un moyen de faire une copie du InputStream fourni avant de l'emballer? Merci

+1

Vous savez que le flux non compressé sera pratiquement inutile? –

+1

Vous devez fournir un 'Charset' spécifique lors de la création d'un' InputStreamReader' plutôt que de l'ignorer et de laisser la plateforme par défaut être utilisée. – ColinD

+0

Tom, pourriez-vous clarifier ce que vous voulez dire par "le flux déballé sera à peu près inutile"? – user389591

Répondre

3

Ce que je vais essayer serait redéfinissant la méthode close:

BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)){ 
    public void close() throws IOException { 
     synchronized (lock) { 
      if (in == null) 
       return; 
     } 
    } 
}; 
// rest of your code 

un peu fou, mais il devrait fonctionner. Cependant, je ne suis pas sûr que ce soit la meilleure approche.

Je pense que c'est une question intéressante, alors j'espère que quelqu'un d'expert donnera son opinion.

4

Personnellement, je voudrais juste éviter le problème en changeant la signature de votre méthode pour exiger qu'un BufferedReader (ou lecteur) être transmis dans.

+0

Cela propage la création de BufferedReader à l'appelant. Mais que se passe-t-il si la méthode d'appel obtient son flux d'ailleurs? –

+1

Vous avez un bon point: vous pouvez également fournir une version '' Reader'. Parce que, si quelqu'un obtient un 'InputStream' avec un codage non-par défaut, il ne peut pas utiliser la méthode basée sur le flux, parce que le InputStreamReader utilise le mauvais codage. –

+0

La classe 'java.util.Properties' fournit à la fois les méthodes' load (InputStream inStream) 'et' load (Reader reader) '. Je pense que les deux options disponibles aux clients possibles de votre classe est une commodité qui peut simplifier le code client. C'est-à-dire que le client n'a pas besoin d'envelopper 'InputStream' pour obtenir un' Reader' avant de le passer en argument de la méthode. – user389591

9

Vous n'avez pas besoin de fermer un BufferedReader ou InputStreamReader ou probablement la plupart des implémentations de lecteur , lorsque vous ne souhaitez pas fermer le lecteur sous-jacent.

Ces lecteurs ne détiennent aucune ressource qu'un appel à close() libérerait et que le garbage collector ne libérerait pas de toute façon (par exemple des ressources natives ou des valeurs dans des variables statiques) lorsque vous laisser tomber la référence au lecteur à la fin de votre méthode.

Les flux d'entrée sous-jacents qui communiquent avec des ressources natives, par ex. FileInputStream ou les flux obtenus à partir d'URL, doivent être fermés pour libérer ces ressources natives.

Pour Writer, il existe une différence en ce que close() appelle généralement flush(). Mais alors, vous pouvez appeler directement le flush().

+1

Oui, bien que certains flux de compression (mais pas 'Readers' pour autant que je sache) utilisent des ressources natives et doivent être fermés. –

+0

En effet. Donc, quand vous vouliez concaténer plusieurs flux de sortie, chacun compressé par lui-même, en un seul flux de sortie, une option est de surcharger la méthode close comme le suggère @Cristian C. (Quelque chose de similaire se produit probablement lors de l'utilisation d'archives compressées contenant plusieurs fichiers.) –

Questions connexes