java - Java 中的异步 File.copy

标签 java nio completable-future

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

我想要实现的是从 Internet 下载一系列 ~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# 方法是否在内部执行相同的操作(我的意思是,必须下载该文件,对吗?)。

有没有更好的方法来实现这一点?

最佳答案

AsynchronousFileChannel (简称 AFC)是在 Java 中使用非阻塞 IO 管理文件的正确方法。不幸的是,它没有提供基于 promise (在 .net 中也称为 Task)的 API,例如 CopyToAsync(Stream) .Net 的。

替代方案 RxIo库建立在 AFC 之上并提供 AsyncFiles具有不同调用习惯的异步 API:基于回调,CompletableFuture (相当于 .net Task )以及 react 流。

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

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 */)

请注意,continuation 是由后台线程调用的 AsynchronousChannelGroup .

因此,您可以使用非阻塞 HTTP 客户端解决您的问题,使用 ComplableFutureAsyncFiles 链接的基于 API用。例如,AHC 是有效的选择。在此处查看用法:https://github.com/AsyncHttpClient/async-http-client#using-continuations

关于java - Java 中的异步 File.copy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47209167/

相关文章:

java - 如何创建使用缓存值的 CompletableFuture?

java - 使用 Camel 发送带有自定义 MIME 消息的邮件

java - 使用 iText 将 HTML 字符串转换为 pdf

java - Java NIO 是如何分解消息的?

java - 在 ByteBuffer 中写入混合数据类型

java - 如何绕过 java.nio.file.DirectoryNotEmptyException?

java - JPA AttributeConverter 是否有可能知道有关 Entity 正在运行的任何信息?

java - Spring 批处理 :How to monitor currently running jobs & show progress on jsp page

java - 是否有可能在具有 Completable future 的 Java 中为 IO 密集型服务获得高吞吐量(4-5 TPS),或者 NodeJs 是更好的选择

asynchronous - 使用 Spring @Async 时跟踪多个异步请求的状态