如何在异步httpclient java 11中将多个异步get请求的响应写入单个文件?
How to write responses of multiple asynchronous get requests to a single file in asynchronous httpclient java 11?
我可以像这样在 java 11 中使用 httpclient 下载单个媒体文件
public class Httptest {
private static HttpClient client = HttpClient.newBuilder().build();
public static void main(String[] args) throws Exception {
File fts = new File("P:/sample.ts"); //Destination of downloaded file
fts.createNewFile();
URI url = new URI("File url here"); //File Url
HttpRequest request = HttpRequest.newBuilder() //Creating HttpRequest using Builder class
.GET()
.uri(url)
.build();
Path file = Path.of("P:/samp.ts");
//BodyHandlers class has methods to handle the response body
// In this case, save it as a file (BodyHandlers.ofFile())
HttpResponse<Path> response = client.send(request,BodyHandlers.ofFile(file));
}
}
以上代码片段从 url 下载 .ts 文件。并且下载正常
现在,我有 url 的列表,List<URI> urls
。我对 url 的列表进行了异步调用,并且还通过添加 Executor service
来确保并发调用。
我卡住的地方是,如何将响应列表写入单个文件。
到目前为止我写的代码:
public class httptest{
// Concurrent requests are made in 4 threads
private static ExecutorService executorService = Executors.newFixedThreadPool(4);
//HttpClient built along with executorservice
private static HttpClient client = HttpClient.newBuilder()
.executor(executorService)
.build();
public static void main(String[] args) throws Exception{
File fts = new File("P:/Spyder_directory/sample.ts");
fts.createNewFile();
List<URI> urls = Arrays.asList(
new URI("Url of file 1"),
new URI("Url of file 2"),
new URI("Url of file 3"),
new URI("Url of file 4"),
new URI("Url of file 5"));
List<HttpRequest> requests = urls.stream()
.map(HttpRequest::newBuilder)
.map(requestBuilder -> requestBuilder.build())
.collect(toList());
Path file = Path.of("P:/Spyder_directory/sample.ts");
List<CompletableFuture<HttpResponse<Path>>> results = requests.stream()
.map(individual_req -> client.sendAsync(individual_req,BodyHandlers.ofFile(file)))
.collect(Collectors.toList());
}
}
执行结束时创建的文件sample.ts
没有请求的响应。
如果你明白我的问题的要点,谁能为这个问题提出替代解决方案。
一种可能性是使用 HttpResponse.BodyHandlers.ofByteArrayConsumer 和 Consumer<Optional<byte[]>>
将字节写入文件。这将使您可以控制文件的打开方式,允许您附加到现有文件而不是每次都创建一个新文件。
请注意,如果这样做,则不应使用 sendAsync
,因为请求将同时发送,因此也会同时接收响应。如果您仍想并发发送请求,则需要缓冲响应并在将它们写入文件时强加一些同步。
我可以像这样在 java 11 中使用 httpclient 下载单个媒体文件
public class Httptest {
private static HttpClient client = HttpClient.newBuilder().build();
public static void main(String[] args) throws Exception {
File fts = new File("P:/sample.ts"); //Destination of downloaded file
fts.createNewFile();
URI url = new URI("File url here"); //File Url
HttpRequest request = HttpRequest.newBuilder() //Creating HttpRequest using Builder class
.GET()
.uri(url)
.build();
Path file = Path.of("P:/samp.ts");
//BodyHandlers class has methods to handle the response body
// In this case, save it as a file (BodyHandlers.ofFile())
HttpResponse<Path> response = client.send(request,BodyHandlers.ofFile(file));
}
}
以上代码片段从 url 下载 .ts 文件。并且下载正常
现在,我有 url 的列表,List<URI> urls
。我对 url 的列表进行了异步调用,并且还通过添加 Executor service
来确保并发调用。
我卡住的地方是,如何将响应列表写入单个文件。
到目前为止我写的代码:
public class httptest{
// Concurrent requests are made in 4 threads
private static ExecutorService executorService = Executors.newFixedThreadPool(4);
//HttpClient built along with executorservice
private static HttpClient client = HttpClient.newBuilder()
.executor(executorService)
.build();
public static void main(String[] args) throws Exception{
File fts = new File("P:/Spyder_directory/sample.ts");
fts.createNewFile();
List<URI> urls = Arrays.asList(
new URI("Url of file 1"),
new URI("Url of file 2"),
new URI("Url of file 3"),
new URI("Url of file 4"),
new URI("Url of file 5"));
List<HttpRequest> requests = urls.stream()
.map(HttpRequest::newBuilder)
.map(requestBuilder -> requestBuilder.build())
.collect(toList());
Path file = Path.of("P:/Spyder_directory/sample.ts");
List<CompletableFuture<HttpResponse<Path>>> results = requests.stream()
.map(individual_req -> client.sendAsync(individual_req,BodyHandlers.ofFile(file)))
.collect(Collectors.toList());
}
}
执行结束时创建的文件sample.ts
没有请求的响应。
如果你明白我的问题的要点,谁能为这个问题提出替代解决方案。
一种可能性是使用 HttpResponse.BodyHandlers.ofByteArrayConsumer 和 Consumer<Optional<byte[]>>
将字节写入文件。这将使您可以控制文件的打开方式,允许您附加到现有文件而不是每次都创建一个新文件。
请注意,如果这样做,则不应使用 sendAsync
,因为请求将同时发送,因此也会同时接收响应。如果您仍想并发发送请求,则需要缓冲响应并在将它们写入文件时强加一些同步。