是否有一个简单的“tee”过滤器用于Java流?

时间:2011-05-18 11:02:46

标签: java android

对于调试purpouses,我想在处理输出流的内容时将其转储到文件中。该流由org.xml.sax.XMLReader解析,它将包含数据。

我认为需要一个过滤器来存档这个,在写一个我自己之前我想问一下是否已经准备好了版本。

更新

应该提到我在Android上工作。

我有什么:

        final org.apache.http.HttpEntity responseEntity = response.getEntity ();
        final java.io.InputStream content = responseEntity.getContent ();
        final java.io.InputStreamReader contentReader =
           new java.io.InputStreamReader (content, "UTF-8");

所以我有java.io.InputStreamInputStreamReader

5 个答案:

答案 0 :(得分:12)

答案 1 :(得分:2)

不是很准备好的,但this可能会引起人们的兴趣。示例中有一个TeeOutputStream实现。

答案 2 :(得分:1)

感谢所有指针。这是我为解决问题而创建的类的副本:

/**
 * <p>
 * Tee-Filters a Reader into an Writer.
 * </p>
 * 
 * @author "Martin Krischik" <martin.krischik@noser.com>
 * @version 1.0 $Revision: 1046 $
 * @since 1.0
 */
public class TeeReader
   extends
      java.io.Reader
{
   /**
    * <p>
    * Reader to read from
    * </p>
    */
   private final java.io.Reader in;
   /**
    * <p>
    * Tee output to which read date is written before beeing passed on.
    * </p>
    */
   private final java.io.Writer tee;

   /**
    * <p>
    * create new filter.
    * </p>
    * 
    * @param in
    *           Reader to read from
    * @param tee
    *           Tee output to which read date is written before beeing passed
    *           on.
    */
   public TeeReader (final java.io.Reader in, final java.io.Writer tee)
   {
      this.in = in;
      this.tee = tee;
   } // TeeReader

   /**
    * <p>
    * Close the stream. Once a stream has been closed, further read(), ready(),
    * mark(), or reset() invocations will throw an IOException. Closing a
    * previously-closed stream, however, has no effect.
    * </p>
    * 
    * @throws java.io.IOException
    * @see java.io.Reader#close()
    */
   @Override
   public void close ()
      throws java.io.IOException
   {
      this.in.close ();
   } // close

   /**
    * <p>
    * Reads characters into a portion of an array. This method will block until
    * some input is available, an I/O error occurs, or the end of the stream is
    * reached.
    * </p>
    * 
    * @param cbuf
    *           Destination buffer
    * @param off
    *           Offset at which to start storing characters
    * @param len
    *           Maximum number of characters to read
    * @return The number of characters read, or -1 if the end of the stream has
    *         been reached Throws:
    * @throws java.io.IOException
    * @see java.io.Reader#read(char[], int, int)
    */
   @Override
   public int read (final char [] cbuf, final int off, final int len)
      throws java.io.IOException
   {
      final int retval = this.in.read (cbuf, off, len);

      if (retval >= 0)
      {
         this.tee.write (cbuf, off, len);
      }
      else
      {
         this.tee.close ();
      } // if

      return retval;
   } // read
} // TeeReader

答案 3 :(得分:0)

这是一个简单的输出流版本(无异常处理):

   public class TeeOutputStream extends OutputStream
   {
           private OutputStream[] streams;

           public TeeOutputStream(final OutputStream ... streams)
           {
                   this.streams = streams;
           }

           @Override
           public void close() throws IOException
           {
                   for (OutputStream stream : streams)
                   {
                           stream.close();
                   }
           }

           @Override
           public void flush() throws IOException
           {
                   for (OutputStream stream : streams)
                   {
                           stream.flush();
                   }

           }

           @Override
           public void write(final byte[] buffer) throws IOException
           {
                   for (OutputStream stream : streams)
                   {
                           stream.write(buffer);
                   }

           }

           @Override
           public void write(final byte[] buffer, final int offset, final int count) throws IOException
           {
                   for (OutputStream stream : streams)
                   {
                           stream.write(buffer, offset, count);
                   }

           }

           @Override
           public void write(final int i) throws IOException
           {
                   for (OutputStream stream : streams)
                   {
                           stream.write(i);
                   }
           }
   }

答案 4 :(得分:0)

我遇到了同样的问题。我希望能够看到Xml解析器的内容,以便我可以调试服务器端脚本。理想情况下,您希望将Xml发送到Xml解析器和LogCat。您可以使用随附的clss InputStreamIntercept来执行此操作。只需通过它运行输入流:

final java.io.InputStream content = 
          new InputStreamIntercept(responseEntity.getContent());

这是班级:

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import android.util.Log;

/**
 * This custom stream filter can intercept data being
 * sent to another stream and send it to LogCat. It is 
 * useful as a way to tell what is being sent to an
 * Xml parser.
 */
public class InputStreamIntercept extends FilterInputStream {

    /**
     * The string we build from data we input.
     */
    private StringBuilder sb = new StringBuilder();

    /**
     * Constructor.
     * @param in the stream we are intercepting
     */
    public InputStreamIntercept(InputStream in) {
        super(in);
    }

    /**
     * Intercept read() and store the character for output
     * @returns -1 if nothing read or the character read
     */
    @Override
    public int read() throws IOException {
        int ret = super.read();
        if(ret >= 0) {
            newChar((byte)ret);
        }
        return ret;
    }

    /**
     * Intercept read and output the content to Log.i.
     */
    @Override
    public int read(byte[] buffer, int offset, int count) throws IOException {
        int ret = super.read(buffer, offset, count);
        for(int i=0;  i<ret;  i++) {
            newChar(buffer[i]);
        }
        return ret;
    }


    /**
     * Handle a new character. We output whenever we get a newline
     * @param ch
     */
    private void newChar(byte ch) {
        if(ch == 10) {
            String str = sb.toString();
            if(str.equals("")) {
                Log.i("debug", "--blank line--");
            } else {
                Log.i("debug", str);
            }

            sb = new StringBuilder();
        } else if(ch == 13) {
            // Skip this character
        } else {
            sb.append((char)ch);
        }
    }

    /**
     * Close the stream
     */
    @Override
    public void close() throws IOException {
        super.close();
        if(sb.length() > 0) {
            Log.i("debug", sb.toString());
        }
    }

}