daydreamer
daydreamer

Reputation: 92139

How do I wait to see if my InputStream has received all data to process further?

I have to write data to Amazon S3 and I write data using OutputStream to its InputStream as follows

    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream;
    try {
        inputStream = new PipedInputStream(outputStream);
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        PutObjectRequest putObjectRequest = new PutObjectRequest(S3EnvironmentConfigurator.BucketTypes.source.name(), getProposalName(uniqueId), inputStream, null);
                        amazonS3Client.putObject(putObjectRequest);
                        try {
                            inputStream.close();
                        } catch (IOException e) {

                        }
                    }
                }
        ).start();

Now amazonS3Client.putObject looks like

  @Override
    public PutObjectResult putObject(@Nonnull final PutObjectRequest putObjectRequest)
            throws AmazonClientException, AmazonServiceException {

        try {
            InputStreamReader is = new InputStreamReader(new GZIPInputStream(putObjectRequest.getInputStream()));
            StringBuilder sb=new StringBuilder();
            BufferedReader br = new BufferedReader(is);
            String read = br.readLine();
            while(read != null) {
                System.out.println(read);
                read =br.readLine();

            }
        } catch (IOException e) {
            //ignore
        }
    return super.putObject(putObjectRequest);

Needed

How can I do something like

while (putObjectRequest.getInputStream() is not completely available) {
   // wait
}

// write inputStream, the entire InputStream is ready and available for processing

Upvotes: 1

Views: 4499

Answers (2)

Mikita Belahlazau
Mikita Belahlazau

Reputation: 15434

You can copy all data to byte buffer and thus be sure that you've read all data from input stream. And then create new input stream based on this buffer. Something like:

byte[] array = IOUtils.toByteArray(inputStream);
InputStream newInputStream = new ByteArrayInputStream(array);

IOUtils from apache commons.

Upvotes: 1

Mike Samuel
Mike Samuel

Reputation: 120576

Once the side writing closes its OutputStream, the InputStream will deliver any bytes that have not yet been read, and then the next read() after that will return -1 to indicate end of input.

The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

If the side writing fails to close() when its done, then the reader will block waiting for more input until the writing process closes.

Upvotes: 1

Related Questions