50 votes

Utilisation de flush() avant close()

Selon la documentation java, invoquer close() sur n'importe quel flux java.io invoque automatiquement flush(). Mais j'ai vu dans de nombreux exemples, même dans des codes de production, des développeurs utiliser explicitement flush() juste avant close(). Dans quelles conditions devons-nous utiliser flush() juste avant close() ?

1 votes

Cette question peut vous aider un peu [voir ceci] [1] [1] : stackoverflow.com/questions/7300676/when-to-use-flush-in-java

7 votes

@Siva : as per the Javadoc . Citation et lien, ou ça n'existe pas. Pour autant que je sache, algunos Les implémentations de flux se videront à la fermeture, tandis que d'autres ne le feront pas. Prouvez-moi que j'ai tort si ce n'est pas le cas et que la Javadoc dit le contraire.

3 votes

Même question que haylem. J'ai lu la documentation de l'API Java de quelques classes et certaines disent que flush() est appelé dans close() tandis que d'autres ne font aucun commentaire à ce sujet. Un lien ?

31voto

Peter Lawrey Points 229686

Les développeurs prennent l'habitude d'appeler flush() après avoir écrit quelque chose qui doit être envoyé.

IMHO L'utilisation de flush() puis de close() est courante lorsqu'il vient d'y avoir une écriture, par ex.

// write a message
out.write(buffer, 0, size);
out.flush();

// finished
out.close();

Comme vous pouvez le constater, la fonction flush() est redondante, mais elle signifie que vous suivez un modèle.

19 votes

Redondant + modèle = anti-modèle ?

12 votes

En fonction de la classe d'implants, cela peut ne pas être redondant. Par exemple, si someinterface.getOutputStream() renvoie un OutputStream, il se peut que vous ne sachiez pas si la méthode close appelle flush ou si la méthode flush est vide, si cela n'est pas explicitement documenté. Par exemple, URLConnection.getOutputStream() : docs.oracle.com/javase/8/docs/api/java/net/

31voto

Bozho Points 273663

Je suppose que dans de nombreux cas, c'est parce qu'ils ne savent pas close() invoque également flush() donc ils veulent être en sécurité.

Quoi qu'il en soit, l'utilisation d'un flux mis en mémoire tampon devrait rendre la purge manuelle presque superflue.

5 votes

Upvoted. N'importe qui, en fait, ne devrait pas supposer que tous les close() invoque également flush() .

1 votes

@JinKwon Ils ont parfaitement le droit de faire cela pour tout flux de sortie qui s'étend. FilterOutputStream : voir la Javadoc.

8voto

Fabian Points 1064

Je tiens à souligner un concept important auquel de nombreux commentaires précédents ont fait allusion :

Un cours d'eau close() La méthode fait Pas nécessairement invoquez flush() .

Par exemple org.apache.axis.utils.ByteArray #close() n'invoque pas flush() .
(cliquez sur le lien pour voir le code source)

Il en va de même, de manière plus générale, pour toute mise en œuvre de l'option Flushable y Closeable . Un exemple marquant étant java.io.PrintWriter . Son site close() ne fait PAS appel à la méthode flush() .
(cliquez sur le lien pour voir le code source)

Cela pourrait expliquer pourquoi les développeurs font preuve de prudence en appelant flush() avant de fermer leurs flux. J'ai personnellement rencontré des bugs de production dans lesquels close() a été appelé sur une instance PrintWriter sans avoir préalablement appelé flush() .

2voto

stackoverflowed Points 57

Les réponses déjà fournies donnent des indications intéressantes que je vais essayer de compiler ici.

Closeable y Flushable étant deux caractères indépendants, Closeable ne précisent pas que close() devrait appeler flush() . Cela signifie que c'est à la documentation (ou au code) de l'implémentation de préciser si flush() est appelé ou non. Dans la plupart des cas, c'est la norme, mais il n'y a aucune garantie.

Maintenant, en ce qui concerne ce que @Fabian a écrit : Il est vrai que java.io.PrintWriter 's close() ne fait pas appel à la méthode flush() . Cependant, il appelle out.close() ( out étant l'auteur sous-jacent). En supposant que out es un BufferedWriter nous allons bien depuis BufferedWriter.close() est en train de tirer la chasse d'eau (d'après son doc). Si c'était un autre écrivain, ce ne serait peut-être pas le cas...

Vous avez donc deux choix :

  • soit vous vous assurez qu'au moins un Writer/Stream interne se vide de lui-même (attention en cas de refactoring du code),
  • ou vous appelez simplement flush() et vous êtes toujours du bon côté.

La solution 2, qui demande moins de travail, est celle que je préfère.

-2voto

E_X Points 83

En utilisant le flush() écrit immédiatement les données mises en mémoire tampon sur le disque (ou presque immédiatement), donc parfois vous voulez vous assurer que ce que vous écrivez est stocké avant de fermer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X