Alors, je l'alimentation des données de fichier à une API qui prend un On dirait qu'il devrait être simple d'écrire un (Alternativement, cela pourrait signaler des octets absolus, et quelqu'un d'autre pourrait faire les mathématiques - peut-être plus généralement utile dans le cas d'autres situations de streaming.) P>
Je sais que j'ai déjà vu cela avant et je peux même l'avoir fait auparavant, mais je ne trouve pas le code et je suis paresseux. Quelqu'un at-il autour de la pose? Ou quelqu'un peut-il suggérer une meilleure approche? P>
Un an (et un peu) plus tard ... strong> p>
Je mis en œuvre une solution basée sur la réponse de Adamski ci-dessous, et cela a fonctionné, mais après quelques mois d'utilisation, je ne le recommanderais pas. Lorsque vous avez beaucoup de mises à jour, tirez / gérer des événements de progrès inutiles devient un coût considérable. Le mécanisme de comptage de base est bien, mais beaucoup mieux d'avoir celui qui se soucie du sondage progrès pour elle, plutôt que de pousser à eux. P>
(Si vous connaissez la taille totale, vous pouvez essayer uniquement de tirer un événement tous les> 1% de changement ou autre, mais cela ne vaut pas vraiment la peine. Et souvent, vous ne le faites pas.) P> Lecteur code>, et je voudrais un moyen de progression du rapport. P>
filtreInputtream code> implémentation qui envoie le fichier
fileInputStream code>, garde la trace du nombre d'octets lus par rapport à la taille totale du fichier, et déclenche un événement (ou, en appelle
mise à jour () code>) faire état de progrès fractionnelle. p>
5 Réponses :
Si vous construisez une application d'interface graphique, il y a toujours introuvable code> dans la manière dont vous décrivez est un point évident et prend moins de temps que de poster une question ici. P>
Ouais, j'ai regardé ça. C'est une application d'interface graphique, mais elle est assez complexe et que les rapports d'avancement ne sont pas une question de faire apparaître une standard progressMonitor code>. Emballage du
InputStream code> prendrait moins de temps que de poster une question, mais je ne saurais jamais si quelqu'un est une meilleure idée.
Voici une implémentation assez basique qui incendie code: p> PropertyChangeEvent code> S lorsque des octets supplémentaires sont lus. Quelques réserves:
Mark code> ou
réinitialiser les opérations code>, bien que ce soit facile à ajouter. LI>
Pas mal. J'aurais probablement oublié sauter () code>. :)
@David: Pour être honnête Mise en œuvre Skip signifiait introduire des lanceurs de Nasty (int) Donc, si vous savez que vous n'en avez pas besoin, je jetterais une idée non supportée ici aussi.
Vous devez également vérifier que super.read () code> ne renvoie pas de négatif (fin des données).
Je pense qu'il y a toujours un bug là-bas. La mise en œuvre de Lecture (octet [] b) code> devrait simplement être
Retour Lecture (B, 0, B.Length); Code> ( Sans b> Progrès mettre à jour). Dans la mise en œuvre actuelle, appeler
Lecture (octet [] B) code> fait compter les octets de lecture deux fois i>, parce que la mise en œuvre de
filtreInputStream # lire (octet [] b) code> appelle directement
Lecture (octet [] B, int Off, int Len) code>.
GUAVA 'S com.google.common.io code> package peut aider vous un peu. Ce qui suit est intronuré et non testé mais devrait vous mettre sur la bonne voie.
long total = file1.length();
long progress = 0;
final OutputStream out = new FileOutputStream(file2);
boolean success = false;
try {
ByteStreams.readBytes(Files.newInputStreamSupplier(file1),
new ByteProcessor<Void>() {
public boolean processBytes(byte[] buffer, int offset, int length)
throws IOException {
out.write(buffer, offset, length);
progress += length;
updateProgressBar((double) progress / total);
// or only update it periodically, if you prefer
}
public Void getResult() {
return null;
}
});
success = true;
} finally {
Closeables.close(out, !success);
}
Connaissez-vous de manière fiable de le faire avec une URL et non un fichier? Quel bug me est le moyen de trouver la longueur du contenu de l'URL. Comme indiqué ici, il semble y avoir aucun moyen de connaître la taille du flux si nous utilisons la compression GZIP. Android-Developers.Blogspot.fr/2011/09/... < / a>
(Ce commentaire ne devrait-il pas être attaché à cette réponse alors?)
La réponse par Adamski fonctionne, mais il y a un petit bug. Le remplacement ne pas remplacer Lecture (octet [] B) code> procédés appelle la méthode
Lecture (octet [] B, int Off Off, int Off Off, int Len) Code> Méthode The Super Class.
Donc, updateprogress (NumbytesReadeDeadeadeDeDead) > est appelé deux fois pour chaque action de lecture et vous vous retrouvez avec un
numbytesread code> c'est-à-dire deux fois la taille du fichier après que le fichier total a été lu. p>
lis (octet [] b) code> La méthode résout le problème. p>
Cela doit être un commentaire de la réponse @adamski et non une réponse par elle-même au moins si vous ne mettez pas le code corrigé dans votre réponse.
Pour compléter la réponse donnée par @kevin Bourillion, elle peut également être appliquée à un contenu réseau également en utilisant cette technique (qui empêche la lecture du flux deux fois: une pour la taille et une pour le contenu):
public class ProgressByteProcessor implements ByteProcessor< Void > { private OutputStream bos; private long progress; private long total; public ProgressByteProcessor( OutputStream bos, long total ) { this.bos = bos; this.total = total; } public boolean processBytes( byte[] buffer, int offset, int length ) throws IOException { bos.write( buffer, offset, length ); progress += length - offset; publishProgress( (float) progress / total ); return true; } public Void getResult() { return null; } }
PS: Cela ne doit pas fonctionner avec des urlconnections comprimées gzippées.