InputStream ou Lecteur de wrapper pour les rapports sur les progrès
Donc, je suis d'alimentation du fichier de données à une API qui prend un Reader
, et je voudrais un moyen de faire rapport des progrès accomplis.
Il semble que cela devrait être simple à écrire un FilterInputStream
de mise en œuvre qui enveloppe le FileInputStream
, garde la trace du nombre d'octets lus vs la taille totale du fichier, et les feux de certains événements (ou les appels de certains update()
méthode) pour signaler les fractions de progrès.
(Sinon, il pourrait faire un rapport absolu octets lus, et quelqu'un d'autre pourrait faire le calcul, peut-être plus généralement utile dans le cas des autres streaming situations).
Je sais que j'ai vu ça avant, et je peux même l'avoir fait avant, mais je ne trouve pas le code et je suis paresseux. Quelqu'un a eu autour de la pose? Ou quelqu'un peut-il suggérer une meilleure approche?
D'un an (et un peu plus tard...
J'ai mis en place une solution basée sur Adamski la réponse ci-dessous, et cela a fonctionné, mais après quelques mois d'utilisation je ne le recommande pas. Lorsque vous avez beaucoup de mises à jour, tir/manipulation inutile des progrès événements devient un coût énorme. Le mécanisme de comptage de base est très bien, mais beaucoup mieux que quiconque se soucie de l'avancement du sondage pour elle, plutôt que de les pousser à eux.
(Si vous savez la taille totale, vous pouvez essayer seulement de déclencher un événement chaque > changement de 1% ou que ce soit, mais ce n'est pas vraiment la peine. Et souvent, vous n'avez pas.)
OriginalL'auteur David Moles | 2009-08-27
Vous devez vous connecter pour publier un commentaire.
Voici un pas assez mise en œuvre de base que les feux de
PropertyChangeEvent
s quand d'autres octets sont lus. Quelques mises en garde:mark
oureset
opérations, bien que celles-ci seraient faciles à ajouter.Code:
skip()
. 🙂Pour être honnête, la mise en œuvre de sauter fallait introduire méchant (int) jette donc, si vous savez que vous n'en avez pas besoin, je jetterais une UnsupportedOperationException ici aussi.
Vous devez aussi vérifier que
super.read()
n'avez pas de retour négatif (fin des données).Je pense qu'il y a encore un bug là. La mise en œuvre de
read(byte[]b)
faut juste êtrereturn read(b, 0, b.length);
(sans une mise à jour des progrès). Dans l'implémentation actuelle, appelantread(byte[]b)
causes les octets lus à être comptés double, parce que la mise en œuvre deFilterInputStream#read(byte[]b)
appelle directementread(byte[]b,int off,int len)
.OriginalL'auteur Adamski
Goyave's
com.google.common.io
package peut vous aider un peu. Ce qui suit est non et non testé mais devrait vous mettre sur la bonne voie.Cela peut ressembler à beaucoup de code, mais je crois que c'est le moins que vous obtiendrez. (remarque: d'autres réponses à cette question ne donnent pas complète exemples de code, il est donc difficile de les comparer entre eux de cette façon.)
La réponse par Adamski fonctionne, mais il y a un petit bug. Le substituée read(byte[] b) les appels de méthode read(byte[] b, int off, int len) méthode creux de la super-classe. Donc updateProgress(long numBytesRead) est appelée deux fois pour chaque lecture de l'action et vous vous retrouvez avec un numBytesRead qui est deux fois la taille du fichier après le total des fichier a été lu. Pas primordial read(byte[] b) méthode résout le problème.
(Il ne devrait pas ce commentaire être joint à cette réponse alors?)
OriginalL'auteur Kevin Bourrillion
La réponse par Adamski fonctionne, mais il y a un petit bug. Le substituée
read(byte[] b)
méthode appelle laread(byte[] b, int off, int len)
méthode creux de la super-classe.Donc
updateProgress(long numBytesRead)
est appelé deux fois pour chaque lecture de l'action et vous vous retrouvez avec unnumBytesRead
qui est deux fois la taille du fichier après le total des fichier a été lu.Pas primordial
read(byte[] b)
méthode résout le problème.OriginalL'auteur WillamS
Si vous êtes la construction d'une application graphique, il y a toujours ProgressMonitorInputStream. Si il n'y a pas de GUI impliqué l'enchaînement d'un
InputStream
dans la façon dont vous décrivez est un no-brainer, et prend moins de temps que de poster une question ici.ProgressMonitor
. Habillage de laInputStream
prendrait moins de temps que de poster une question, mais ensuite, je ne sais jamais si quelqu'un a une meilleure idée.OriginalL'auteur Bombe
Pour compléter la réponse donnée par @Kevin Bourillion, il peut être appliqué à un réseau de contenu à l'aide de cette technique (qui empêche la lecture du flux à deux fois : l'une pour la taille et l'autre pour le contenu) :
Où ProgressByteProcessor est un intérieur de classe :
OriginalL'auteur Snicolas