Package com.cloudera.util

Source Code of com.cloudera.util.InputStreamPipe$CopyThread

/**
* Licensed to Cloudera, Inc. under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  Cloudera, Inc. 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
*
*     http://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 com.cloudera.util;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.nio.channels.WritableByteChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Channels that wrap input streams are blocking, so this wrapper creates a
* thread that pumps data from input streams, and presents and nonblocking
* interface to the data.
*/
public class InputStreamPipe {
  static final Logger LOG = LoggerFactory.getLogger(InputStreamPipe.class);
  final InputStream input;
  final Pipe pipe;
  final CopyThread copyThread;

  public InputStreamPipe(InputStream in) throws IOException {
    this.input = in;
    pipe = Pipe.open();

    copyThread = new CopyThread(in, pipe.sink());
  }

  public InputStreamPipe() throws IOException {
    this(System.in);
  }

  public void start() {
    copyThread.start();
  }

  public void shutdown() {
    copyThread.shutdown();
  }

  public SelectableChannel getChannel() throws IOException {
    SelectableChannel channel = pipe.source();

    channel.configureBlocking(false);

    return (channel);
  }

  protected void finalize() {
    copyThread.shutdown();
  }

  // ---------------------------------------------------

  public static class CopyThread extends Thread {
    volatile boolean keepRunning = true;
    InputStream in;
    WritableByteChannel out;

    CopyThread(InputStream in, WritableByteChannel out) {
      this.in = in;
      this.out = out;
      this.setDaemon(true);
    }

    public void shutdown() {
      keepRunning = false;
      this.interrupt();
      try {
        out.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    public void run() {
      byte[] bytes = new byte[4096];
      ByteBuffer buffer = ByteBuffer.wrap(bytes);
      try {
        while (keepRunning) {
          int count = in.read(bytes);
          // 0 = nothing read
          // -1 = EOF
          if (count <= 0) {

            // don't burn cpu if there is no progress
            Clock.sleep(100);
            break;
          }

          buffer.clear().limit(count);

          out.write(buffer);
        }

        out.close();
      } catch (IOException e) {
        LOG.error("Input stream pipe closed", e);
      } catch (InterruptedException e) {
        LOG.info("Input stream pipe interrupted");
      }
    }
  }
}
TOP

Related Classes of com.cloudera.util.InputStreamPipe$CopyThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.