2010-09-17 3 views
3

Nous téléchargeons un fichier à l'aide de la bibliothèque Amazon AWS Java et rencontrons des difficultés pour obtenir la progression du téléchargement. Nous appelons actuellement le suivant:Télécharger un fichier ou InputStream vers S3 avec un rappel de progression

File file = new File(localAsset.getVideoFilePath()); 
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, localAsset.getFileName(), file); 
s3.putObject(putObjectRequest); 

Comment pouvons-nous définir un rappel pour vérifier la progression du téléchargement de fichiers?

Merci

Répondre

5

je suis tombé sur ce problème exact et écrit simple wrapper InputStream qui imprime des barres de progression agréable:

import java.io.IOException; 
import java.io.InputStream; 

import org.apache.commons.vfs.FileContent; 
import org.apache.commons.vfs.FileSystemException; 

public class ProgressInputStream extends InputStream { 
    private final long size; 
    private long progress, lastUpdate = 0; 
    private final InputStream inputStream; 
    private final String name; 
    private boolean closed = false; 

    public ProgressInputStream(String name, InputStream inputStream, long size) { 
     this.size = size; 
     this.inputStream = inputStream; 
     this.name = name; 
    } 

    public ProgressInputStream(String name, FileContent content) 
    throws FileSystemException { 
     this.size = content.getSize(); 
     this.name = name; 
     this.inputStream = content.getInputStream(); 
    } 

    @Override 
    public void close() throws IOException { 
     super.close(); 
     if (closed) throw new IOException("already closed"); 
     closed = true; 
    } 

    @Override 
    public int read() throws IOException { 
     int count = inputStream.read(); 
     if (count > 0) 
      progress += count; 
     lastUpdate = maybeUpdateDisplay(name, progress, lastUpdate, size); 
     return count; 
    } 
    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
     int count = inputStream.read(b, off, len); 
     if (count > 0) 
      progress += count; 
     lastUpdate = maybeUpdateDisplay(name, progress, lastUpdate, size); 
     return count; 
    } 

    static long maybeUpdateDisplay(String name, long progress, long lastUpdate, long size) { 
     if (Config.isInUnitTests()) return lastUpdate; 
     if (size < B_IN_MB/10) return lastUpdate; 
     if (progress - lastUpdate > 1024 * 10) { 
      lastUpdate = progress; 
      int hashes = (int) (((double)progress/(double)size) * 40); 
      if (hashes > 40) hashes = 40; 
      String bar = StringUtils.repeat("#", 
        hashes); 
      bar = StringUtils.rightPad(bar, 40); 
      System.out.format("%s [%s] %.2fMB/%.2fMB\r", 
        name, bar, progress/B_IN_MB, size/B_IN_MB); 
      System.out.flush(); 
     } 
     return lastUpdate; 
    } 
} 

(c'est copier-collé à partir du code en direct, de sorte que vous pourriez avoir à faire quelques correctifs pour le faire fonctionner dans votre propre code.) Ensuite, utilisez simplement la méthode InputStream de mettre les choses (assurez-vous de spécifier la taille!) et cela fera une belle barre de progression pour vous. Si vous voulez un rappel approprié, ce serait plutôt facile à faire.

+0

Merci, ça a très bien fonctionné! – royvandewater

+0

quelle est la valeur de B_IN_MB dans le code ci-dessus – koti

+0

@koti devrait être des octets en mégaoctets (1024^3) :) – knalli

0

Il y a actuellement aucun moyen facile de le faire « intégré », mais vous pouvez facilement mettre en œuvre un en enveloppant le InputStream vous passez pour un rapport sur la façon dont il est loin d'être lu.

Vous pouvez lire le team's official response à cette question sur leurs forums.

Il pourrait également être intéressant de noter que le kit de développement .NET ne ont cette fonctionnalité, mais pour autant que je sache, il est mis en œuvre de manière tout aussi « hackish » (simplement, l'API S3 lui-même ne vraiment pas construit -dans les dispositions pour le faire gracieusement). Si vous éprouvez des difficultés à le mettre en œuvre vous-même, cela pourrait être une source d'inspiration.

0

Utiliser auditeur de progrès pour suivre les progrès

File file = new File(localAsset.getVideoFilePath()); 
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, localAsset.getFileName(), file); 

putObjectRequest.setGeneralProgressListener(new ProgressListener() { 
     long transferred = 0; 

     @Override 
     public void progressChanged(ProgressEvent progressEvent) { 
      transferred += progressEvent.getBytesTransferred(); 
      Timber.i("Transferred %f%%", code, ((float)transferred/(float) fileSize) * 100f); 
     } 
    }); 

s3.putObject(putObjectRequest); 
Questions connexes