使用进度回调将文件或InputStream上载到S3

我们正在使用Amazon AWS Java Library上传文件,但很难获得上传进度。 我们目前正在调用以下内容:

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

我们如何设置回调来检查文件上传进度?

谢谢

我遇到了这个确切的问题,写了一个简单的InputStream包装器,打印出好的进度条:

 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; } } 

(这是从实时代码中复制粘贴的,因此您可能需要进行一些修复才能使其在您自己的代码中工作。)

然后,只需使用InputStream放置东西的方式(确保指定大小!),它将为您提供一个很好的进度条。 如果你想要一个适当的回调,那也很容易。

目前还没有简单的方法来实现“内置”,但您可以通过包装传入的InputStream来轻松实现一个,以报告它的读取距离。

您可以在论坛上阅读该团队对此问题的官方回复 。

值得注意的是,.NET SDK 确实具有此function,但据我所知,它以类似的“hackish”方式实现(简单地说,S3 API本身并没有内置的规定来执行此操作优雅)。 如果您自己无法实施,那么这可能是寻找灵感的地方。

使用进度监听器来跟踪进度

 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);