java - 使用进度回调将文件或 InputStream 上传到 S3

标签 java amazon-s3

我们正在使用 Amazon AWS Java 库上传文件,但无法获取上传进度。我们目前正在调用以下内容:

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 方式放置东西(确保指定大小!),它会为您制作一个漂亮的进度条。如果您想要一个适当的回调,那也很容易做到。

关于java - 使用进度回调将文件或 InputStream 上传到 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3739626/

相关文章:

javacc 跳过注释但需要保留有用的注释

amazon-s3 - Amazon S3 创建对象错误 : POST requires exactly one file upload per request

node.js - Node 应用程序流文件直接上传到亚马逊s3

python - 将文件上传到 S3 存储桶 - Python Django

amazon-s3 - 了解预签名 URL 中的 AWS S3 过期值

javascript - 如何将文件从 AWS S3 下载到客户端设备?

java - for 循环如何迭代到下面代码中的下一项

java - 从派生类调用构造函数

java - JNA 中的 RasEnumConnections 函数返回不完整的数据。我做错了什么?

java - 如何在 Jooq 中将毫秒翻译为日期并按月和年分组?