/* * PS3 Media Server, for streaming any medias to your PS3. * Copyright (C) 2008 A.Brochard * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.pms.io; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Use one of the constructors to create a thread (non-blocking) that will * consume an {@link InputStream} and then die. * * Use the static methods to consume an {@link InputStream} in a blocking * manner in the calling thread's context. */ public class StreamGobbler extends Thread { private static final Logger LOGGER = LoggerFactory.getLogger(StreamGobbler.class); BufferedReader in; private boolean logging; /** * Create a new thread that when started will read and discard the {@link InputStream}. * Use this when the stream has to be consumed in a non-blocking fashion. * * @param in the {@link InputStream} to be consumed * @param enableLogging true if the stream content should be logged to TRACE level */ public StreamGobbler(InputStream in, boolean enableLogging) { this.in = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); this.logging = enableLogging; } /** * Create a new thread that when started will read and discard the {@link InputStream}. * Use this when the stream has to be consumed in a non-blocking fashion. * * @param in the {@link InputStream} to be consumed */ public StreamGobbler(InputStream in) { this(in, false); } @Override public void run() { try { doGobble(in, logging); } catch (IOException e) { LOGGER.debug("Caught exception while gobbling stream: {}", e.getMessage()); LOGGER.trace("", e); } } /** * Read and discard the {@link InputStream} in the caller's context * (blocking). Use this when you want to wait for the stream to be consumed. * Note that you cannot handle more than one stream at a time with this, * and thus any process output to be gobbled should be created with * {@link ProcessBuilder} and it's error stream redirected. * * @param in the {@link InputStream} to be consumed * @param enableLogging true if the stream content should be logged to TRACE level * * @throws IOException if any problems occur while consuming the stream */ public static void consumeThrow(InputStream in, boolean enableLogging) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); doGobble(reader, enableLogging); } /** * Read and discard the {@link InputStream} in the caller's context * (blocking). Use this when you want to wait for the stream to be consumed. * Note that you cannot handle more than one stream at a time with this, * and thus any process output to be gobbled should be created with * {@link ProcessBuilder} and it's error stream redirected. * * @param in the {@link InputStream} to be consumed * @param enableLogging true if the stream content should be logged to TRACE level */ public static void consume(InputStream in, boolean enableLogging) { BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); try { doGobble(reader, enableLogging); } catch (IOException e) { LOGGER.debug("Caught exception while gobbling stream: {}", e.getMessage()); LOGGER.trace("", e); } } /** * Read and discard the {@link InputStream} in the caller's context * (blocking). Use this when you want to wait for the stream to be consumed. * Note that you cannot handle more than one stream at a time with this, * and thus any process output to be gobbled should be created with * {@link ProcessBuilder} and it's error stream redirected. * * @param in the {@link InputStream} to be consumed */ public static void consume(InputStream in) { consume(in, false); } private static void doGobble(BufferedReader reader, boolean enableLogging) throws IOException { String line = null; try { while ((line = reader.readLine()) != null) { if (enableLogging && !line.startsWith("100")) { LOGGER.trace(line); } } } finally { reader.close(); } } }