Dan*_*iel 5 java nio completable-future
Java中有没有一种方法可以以异步方式将一个文件复制到另一个文件中?我试图找到类似于C# 中的Stream.CopyToAsync的东西。
我想要实现的是从互联网下载一系列约 40 个文件,这是我为每个文件想到的最好的结果:
CompletableFuture.allOf(myFiles.stream()
.map(file -> CompletableFuture.supplyAsync(() -> syncDownloadFile(file)))
.toArray(CompletableFuture[]::class))
.then(ignored -> doSomethingAfterAllDownloadsAreComplete());
Run Code Online (Sandbox Code Playgroud)
哪里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);
}
}
Run Code Online (Sandbox Code Playgroud)
但这意味着我在任务执行器内部有一些阻塞调用,我想避免这种情况,所以我不会一次阻塞太多执行器。
我不确定 C# 方法内部是否执行相同的操作(我的意思是,必须有东西下载该文件,对吗?)。
有更好的方法来实现这一点吗?
AsynchronousFileChannel(简称AFC)是Java中用非阻塞IO管理文件的正确方式。不幸的是,它没有提供基于 Promise(也称为Task.net 中)的 API,例如CopyToAsync(Stream).Net 的 API。
替代的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 */)
Run Code Online (Sandbox Code Playgroud)
请注意,延续是由后台线程调用的AsynchronousChannelGroup。
因此,您可以使用非阻塞 HTTP 客户端来解决您的问题,并ComplableFuture使用与使用相关的基础 API AsyncFiles。例如,AHC 是有效的选择。请参阅此处的用法:https ://github.com/AsyncHttpClient/async-http-client#using-continuations
| 归档时间: |
|
| 查看次数: |
1698 次 |
| 最近记录: |