Source:
<code>public InputStream streamBlob(final String container, final String name, final ExecutorService executor) { final ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor); final PipedOutputStream output; final PipedInputStream input; try { output = new PipedOutputStream(); input = new PipedInputStream(output, getMinimumMultipartPartSize() * 5 > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) getMinimumMultipartPartSize() * 5); } catch (IOException e) { throw new RuntimeException(e); } final long contentLength = api .getObjectApi(regionId, container) .getWithoutBody(name) .getPayload() .getContentMetadata() .getContentLength(); final long partSize = getMinimumMultipartPartSize(); final LinkedBlockingQueue<ListenableFuture<byte[]>> results = new LinkedBlockingQueue<ListenableFuture<byte[]>>(); listeningExecutor.submit(new Runnable() { @Override public void run() { ListenableFuture<byte[]> result; long from; try { for (from = 0; from < contentLength; from = from + partSize) { logger.debug(Thread.currentThread() + " writing to output"); result = results.take(); if (result == null) { output.close(); input.close(); throw new RuntimeException("Error downloading file part to stream"); } output.write(result.get()); } } catch (Exception e) { logger.debug(e.toString()); Closeables2.closeQuietly(input); <START> Closeables2.closeQuietly(output); <END> throw new RuntimeException(e); } Closeables2.closeQuietly(output); } }); listeningExecutor.submit(new Runnable() { @Override public void run() { long from; long to; for (from = 0; from < contentLength; from = from + partSize) { to = (from + partSize >= contentLength) ? contentLength - 1 : from + partSize - 1; BlobStreamDownloader b = new BlobStreamDownloader(container, name, from, to); results.add(listeningExecutor.submit(b)); } } }); return input; }</code><technical_language>work in a finally block</technical_language>

Target:
public InputStream streamBlob(final String container, final String name, final ExecutorService executor) { final ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor); final PipedOutputStream output; final PipedInputStream input; try { output = new PipedOutputStream(); input = new PipedInputStream(output, getMinimumMultipartPartSize() * 5 > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) getMinimumMultipartPartSize() * 5); } catch (IOException e) { throw new RuntimeException(e); } final long contentLength = api .getObjectApi(regionId, container) .getWithoutBody(name) .getPayload() .getContentMetadata() .getContentLength(); final long partSize = getMinimumMultipartPartSize(); final LinkedBlockingQueue<ListenableFuture<byte[]>> results = new LinkedBlockingQueue<ListenableFuture<byte[]>>(); listeningExecutor.submit(new Runnable() { @Override public void run() { ListenableFuture<byte[]> result; long from; try { for (from = 0; from < contentLength; from = from + partSize) { logger.debug(Thread.currentThread() + " writing to output"); result = results.take(); if (result == null) { output.close(); input.close(); throw new RuntimeException("Error downloading file part to stream"); } output.write(result.get()); } } catch (Exception e) { logger.debug(e.toString()); Closeables2.closeQuietly(input); throw new RuntimeException(e); } finally { Closeables2.closeQuietly(output); } } }); listeningExecutor.submit(new Runnable() { @Override public void run() { long from; long to; for (from = 0; from < contentLength; from = from + partSize) { to = (from + partSize >= contentLength) ? contentLength - 1 : from + partSize - 1; BlobStreamDownloader b = new BlobStreamDownloader(container, name, from, to); results.add(listeningExecutor.submit(b)); } } }); return input; }