Vert.x 下客户端以异步流式上传下载

571 阅读1分钟

Vert.x的好处不必讲,轻量级,没有SpringBoot那样占用大量内存。

最近有个需求是下载文件,有一次文件太大直接内存过载了,网上资料甚少,后来自己看了下源码注释,终于搞定了,在这里记录下。

之前一次性下载的代码如下:

其中有部分过程封装成方法了,比较简单就不贴出来了。

public String download(String savePath){
    WebClient client = WebClient.create(getVertx());
    //创建Http请求
    HttpRequest<Buffer> httpRequest = createHttpRequest(client,url);
    final CompletableFuture<String> future = new CompletableFuture<>();
    //发送请求
    httpRequest.send(resp -> {
            try {
                if (resp.succeeded() && resp.result().statusCode() == 200) {
                    HttpResponse<Buffer> result = resp.result();
                    //讲buffer写入文件
                    bufferToFile(result.body(), savePath);
                    future.complete(savePath);
                } else {
                    future.completeExceptionally(new Exception("exception"));
                }
            } catch (Exception e) {
                future.completeExceptionally(e);
            } finally {
                //释放资源
                release();
            }
        });
    return future.get();
}

修改成流式下载后,先通过FileSystem.open()方法获得一个文件流异步对象,这个异步对象作为流失下载的载体去承接(as(BodyCodec.pipe(asyncFile)))。

public void getFile(String fileName) {
        method = "get";

        Vertx.vertx().fileSystem().open(fileName, new OpenOptions(), res -> {
            AsyncFile asyncFile = res.result();
            WebClient client = WebClient.create(Vertx.vertx());
            HttpRequest<Void> httpRequest = createHttpRequest(client).as(BodyCodec.pipe(asyncFile));
            httpRequest.send(resp -> {
                if (resp != null) {
                    //释放资源
                    release();
                }
            });
        });
 }

流式上传也是类似的

public String uploadStream(String filename) throws Exception {
        WebClient client = WebClient.create(getVertx());
        HttpRequest<Buffer> httpRequest = createHttpRequest(client);

        final CompletableFuture<String> future = new CompletableFuture<>();
        Vertx.vertx().fileSystem().open(filename, new OpenOptions(), res -> {
            httpRequest.sendStream(res.result(), resp -> {
                try {
                    future.complete("ok");
                } catch (Throwable e) {
                    future.completeExceptionally(e);
                } finally {
                     //释放资源
                    res.result().close();
                    release();
                }
            });
        });
        return future.get();
    }