【问题标题】:Asynchronous File.copy in JavaJava中的异步File.copy
【发布时间】:2018-04-22 21:06:00
【问题描述】:

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

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

有没有更好的方法来做到这一点?

【问题讨论】:

  • 您不应该将 CompletableFutures 数组传递给 allOf 而不是 MyFile 数组吗?一旦你调用 toArray 它就会阻塞,直到它填充所有 MyFiles
  • @Novaterata 是的,谢谢。我稍微更改了代码以删除我公司的私人内容,但在此过程中出现了一些问题。
  • 所以你应该把最终的 CompletableFuture 分解成一个变量。然后,您可以做任何其他需要做的事情,并在需要最终结果时调用 completableFuture.get()。在您调用 get() 或 complete() 或类似方法之前它不会阻塞,但它已经开始工作了。
  • 但是在做这项工作的过程中,我所有的工人都会被阻止,不是吗?那是我不确定的部分:可以将长时间运行的同步任务放在工作人员身上吗?或者对于这种将文件复制到另一个文件的情况,有更好的方法吗?

标签: java nio completable-future


【解决方案1】:

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

替代的 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.com/AsyncHttpClient/async-http-client#using-continuations

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-14
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多