【发布时间】: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