Java中的异步File.copy

问题描述 投票:4回答:1

在Java中有没有一种方法可以将一个文件以异步方式复制到另一个文件中?类似于 Stream.CopyToAsync 在C#中,我试图找到的是。

我试图实现的是从互联网上下载一系列约40个文件,这是我为每个文件想出的最佳方案。

CompletableFuture.allOf(myFiles.stream()
        .map(file -> CompletableFuture.supplyAsync(() -> syncDownloadFile(file)))
        .toArray(CompletableFuture[]::class))
    .then(ignored -> doSomethingAfterAllDownloadsAreComplete());

在哪里 syncDownloadFile 是。

private void syncDownloadFile(MyFile file) {
    try (InputStream is = file.mySourceUrl.openStream()) {
        long actualSize = Files.copy(is, file.myDestinationNIOPath);
        // size validation here
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

但这意味着我在任务执行者内部有一些阻塞调用,我想避免这种情况,这样我就不会同时阻塞太多的执行者。

我不知道C#方法内部是否也是这样做的(我的意思是,总得有东西在下载那个文件吧?)。

有没有更好的方法来完成这个任务?

java nio completable-future
1个回答
1
投票

AsynchronousFileChannel (简称AFC)是在Java中用非阻塞IO管理Files的正确方法。遗憾的是,它没有提供一个基于承诺的(也就是作为 Task (在.net中) API,如 CopyToAsync(Stream) .Net的。

替代品 RxIo 库是建立在AFC之上的,并提供了? AsyncFiles 异步API的不同调用习惯:基于回调。CompletableFuture (相当于.net Task),也有反应式流。

例如,虽然可以异步地从一个文件复制到另一个文件。

Path in = Paths.get("input.txt");
Path out = Paths.get("output.txt");
AsyncFiles
      .readAllBytes(in)
      .thenCompose(bytes -> AsyncFiles.writeBytes(out, bytes))
      .thenAccept(index -> /* invoked on completion */)

请注意,连续性是由一个线程从后台调用的。AsynchronousChannelGroup.

因此,你可以使用一个非阻塞的HTTP客户端来解决你的问题,并使用 ComplableFuture 基于API与 AsyncFiles 用。例如,AHC是有效的选择。参见这里的用法。https:/github.comAsyncHttpClientasync-http-client#using-continuations。

© www.soinside.com 2019 - 2024. All rights reserved.