StreamPumper.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.exec;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import org.apache.commons.exec.util.DebugUtils;
- /**
- * Copies all data from an input stream to an output stream.
- */
- public class StreamPumper implements Runnable {
- /** The default size of the internal buffer for copying the streams. */
- private static final int DEFAULT_SIZE = 1024;
- /** The input stream to pump from. */
- private final InputStream is;
- /** The output stream to pmp into. */
- private final OutputStream os;
- /** The size of the internal buffer for copying the streams. */
- private final int size;
- /** Was the end of the stream reached. */
- private boolean finished;
- /** Close the output stream when exhausted. */
- private final boolean closeWhenExhausted;
- /**
- * Constructs a new stream pumper.
- *
- * @param is input stream to read data from.
- * @param os output stream to write data to.
- */
- public StreamPumper(final InputStream is, final OutputStream os) {
- this(is, os, false);
- }
- /**
- * Constructs a new stream pumper.
- *
- * @param is input stream to read data from.
- * @param os output stream to write data to.
- * @param closeWhenExhausted if true, the output stream will be closed when the input is exhausted.
- */
- public StreamPumper(final InputStream is, final OutputStream os, final boolean closeWhenExhausted) {
- this.is = is;
- this.os = os;
- this.size = DEFAULT_SIZE;
- this.closeWhenExhausted = closeWhenExhausted;
- }
- /**
- * Constructs a new stream pumper.
- *
- * @param is input stream to read data from.
- * @param os output stream to write data to.
- * @param closeWhenExhausted if true, the output stream will be closed when the input is exhausted.
- * @param size the size of the internal buffer for copying the streams.
- */
- public StreamPumper(final InputStream is, final OutputStream os, final boolean closeWhenExhausted, final int size) {
- this.is = is;
- this.os = os;
- this.size = size > 0 ? size : DEFAULT_SIZE;
- this.closeWhenExhausted = closeWhenExhausted;
- }
- /**
- * Tests whether the end of the stream has been reached.
- *
- * @return true is the stream has been exhausted.
- */
- public synchronized boolean isFinished() {
- return finished;
- }
- /**
- * Copies data from the input stream to the output stream. Terminates as soon as the input stream is closed or an error occurs.
- */
- @Override
- public void run() {
- synchronized (this) {
- // Just in case this object is reused in the future
- finished = false;
- }
- final byte[] buf = new byte[this.size];
- int length;
- try {
- while ((length = is.read(buf)) > 0) {
- os.write(buf, 0, length);
- }
- } catch (final Exception ignored) {
- // nothing to do - happens quite often with watchdog
- } finally {
- if (closeWhenExhausted) {
- try {
- os.close();
- } catch (final IOException e) {
- final String msg = "Got exception while closing exhausted output stream";
- DebugUtils.handleException(msg, e);
- }
- }
- synchronized (this) {
- finished = true;
- notifyAll();
- }
- }
- }
- /**
- * This method blocks until the stream pumper finishes.
- *
- * @throws InterruptedException if any thread interrupted the current thread before or while the current thread was waiting for a notification.
- * @see #isFinished()
- */
- public synchronized void waitFor() throws InterruptedException {
- while (!isFinished()) {
- wait();
- }
- }
- }