2010-07-02 3 views
0

Je voudrais suivre de près la progression d'un téléchargement de fichier. Je sais que je peux redéfinir MultipartEntity et écrire la méthode writeTo (OutputStream out) dans une classe FilterOutputStream que j'ai créée pour envelopper l'InputStream par défaut. Pour plus de détails sur comment j'ai fait cela, voir ma réponse here. Cependant, en examinant de plus près, cela compte chaque octet envoyé deux fois! Je suis allé à la documentation pour voir ce qui se passait. On dirait que la méthode write(byte[], int, int) de FilterOutputStream appelle simplement la méthode write (byte) de FilterOutputStream dans une boucle. Il recommande des sous-classes pour fournir une méthode plus efficace. Je suppose que ceci implique d'appeler l'écriture de OutputStream sous-jacente (byte [], int, int) et espérer que le OutputStream sous-jacent a une meilleure méthode pour pousser des octets sur le stream (les sous-classes de doc de OutputStream que simplement en boucle sur la méthode OutputStream # write (byte)).Comment étendre correctement la classe Java FilterOutputStream?

C'est là que je me trouve dans une situation difficile. Je ne peux pas garantir que MultipartEntity # writeTo (OutputStream) aboutira toujours à un appel à OutputStream.write (byte [], int, int), donc si je compte les octets envoyés là, je risque de manquer certains qui sont envoyés en utilisant la méthode d'écriture (octet). Cependant, je ne peux pas compter dans la méthode write (byte), car la méthode OutputStream.write (byte [], int, int) ne peut jamais appeler la méthode write (byte). Une réponse consiste à appeler super.write (byte [], int, int) à l'intérieur de la méthode write (byte [], int, int) de ma sous-classe. Ensuite, je sais que cela va simplement boucler sur la méthode d'écriture (octet), en écrivant un octet à la fois. Je peux alors compter tous les octets écrits à l'intérieur de la méthode write (byte). Cependant, ceci est inefficace, et les docs le recommandent directement. Je suis sûr que certaines des sous-classes de OutputStream parviennent à écrire plusieurs octets dans le flux à la fois, il est donc stupide de ne pas utiliser cet avantage. Alors comment remplacer correctement FilterOutputStream pour qu'il soit efficace et compte tous les octets envoyés?

Désolé si cela est long, je l'ai fait un wiki au cas où quelqu'un peut décrire mieux la question que moi

+0

http://www.karlin.mff.cuni.cz/network/prirucky/javatut/java/io/writingFiltered.html – Val

Répondre

3

Il suffit d'appeler write(byte[] b, int off, int len) sur le flux sous-jacent lorsque la même méthode est appelée sur votre flux de comptage. Cela ne provoquera jamais l'appel de la méthode write(byte b) sur le flux de comptage.

En outre, votre CountingOutputStream dans la réponse liée a un certain nombre d'autres problèmes.

  1. Il a sa propre référence au flux de sortie enroulé même si FilterOutputStream stocke pour vous dans un champ de protection appelé out.
  2. Il écrit len octets dans le flux enveloppé lorsque write(byte[] b, int off, int len) est appelé, mais ajoute seulement 1 au nombre d'octets transférés. Il n'incrémente pas les octets transférés en write(byte b).
+0

Colin, merci beaucoup! Cela le rend beaucoup plus clair :) – Hamy

Questions connexes