6

I need to initiate download of some content over HTTP and then read the data as a reactive stream.

So, even though the downloaded data are big, I can almost immediately read the first few bytes of the response body (no need to wait for the whole response body). Then, do some computations and in a few seconds read another portion of the data. There has to be some limit of the cached data, because operation memory can't handle the whole content (its tens of GB).

I've been trying to use HttpClient's sendAsync method with BodyHandlers.ofInputStream(), but it always blocks and waits for all the data to arrive.

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://..."))
    .build();

HttpResponse<InputStream> response = client
    .sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
    .get(); // this finishes as soon as the header is received

try {
    InputStream stream = response.body();
    byte[] test = stream.readNBytes(20); // trying to read just a few bytes
                                         // but it waits for the whole body
} catch (IOException ex) {}

What do I need to change so the response body is downloaded gradually?

Bobulous
  • 12,967
  • 4
  • 37
  • 68
Martin Heralecký
  • 5,649
  • 3
  • 27
  • 65
  • Not very sure, but from the code in question, you seem to be looking out for the [`HttpBodyHandlers.ofByteArrayConsumer`](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandlers.html#ofByteArrayConsumer(java.util.function.Consumer)), is it so? Something on the line `client.sendAsync(request, ofByteArrayConsumer(bytes -> System.out.println(bytes + "received")));` – Naman Dec 16 '18 at 11:28
  • 1
    @nullpointer Unfortunately, using your solution does exactly the same. I put a breakpoint on the `System.out.println(bytes);` line and it's never hit (or at least not until it downloads a gigabyte of data). – Martin Heralecký Dec 16 '18 at 15:44
  • Could you share an MCVE further if possible to try out the actual download of the data you're referring to? Just curious to try things out. – Naman Dec 16 '18 at 17:47
  • 2
    @nullpointer The only thing I didn't post is the URL, which comes with authorization data I cannot share. However, I found out that it actually works when I try to download small files (~5GB instead of ~20GB). I'll test further and let you know. – Martin Heralecký Dec 16 '18 at 18:04

1 Answers1

2

This is a bug. It has been fixed in Java 11.0.2: https://bugs.openjdk.java.net/browse/JDK-8212926

daniel
  • 2,665
  • 1
  • 8
  • 18