code: private static void copyStream(final InputStream inputStream, final OutputStream outputStream, MessageDigest messageDigest) throws IOException,
              InterruptedException {
          // Read the rest of the stream and write to the destination OutputStream.
          final byte[] buffer = new byte[BUFFER_SIZE];
          int bufferLength = 0;
          Exception exception = null;
          try {
              while ((bufferLength = inputStream.read(buffer)) > 0) {
                  if (Thread.currentThread().isInterrupted()) {
                      InterruptedException e = new InterruptedException();
                      throw e;
                  }
                  outputStream.write(buffer, 0, bufferLength);
                  if (messageDigest != null) {
                      messageDigest.update(buffer, 0, bufferLength);
                  }
              }
  
          } catch (Exception e) {
              exception = e;
              if (exception instanceof IOException) {
                  throw (IOException) e;
              }
              if (exception instanceof InterruptedException) {
                  throw (InterruptedException) e;
              }
          } finally {
              // Try to flush the OutputStream
              if (exception == null) {
                  outputStream.flush();
              }
          }
      }
docs: Utility method to write given inputStream to given outputStream and update the messageDigest while transferring the bytes
  
  @param inputStream   the inputStream to copy from.
  @param outputStream  the outputStream to write to.
  @param messageDigest messageDigest to update with the outpu
  @throws IOException          thrown if there was a problem reading from inputStream or writing to outputStream.
  @throws InterruptedException thrown if the thread is interrupted which indicates cancelling.