Utility classes related to stream-based I/O. Highlights:

- {@link edu.emory.mathcs.util.io.Base64Encoder} and {@link edu.emory.mathcs.util.io.Base64Decoder} allow to encode and decode bytes to and from the base64 format. The classes can work both as filtering streams and offline (converting strings to byte arrays and vice versa).
- {@link edu.emory.mathcs.util.io.BufferedPipe} is an in-memory pipe that links an output stream with an input stream via a dynamically sized memory buffer. Such pipes are useful for decoupling data producing threads from data consuming threads in a way that allows to control and minimize memory footprint.
- Various ways of redirecting and splitting streams are handled by {@link edu.emory.mathcs.util.io.ForkOutputStream}, {@link edu.emory.mathcs.util.io.RedirectingInputStream}, {@link edu.emory.mathcs.util.io.RedirectingReader}, and {@link edu.emory.mathcs.util.io.TeeInputStream} classes.
- {@link edu.emory.mathcs.util.io.NullInputStream} and {@link edu.emory.mathcs.util.io.NullOutputStream} provide stream "terminators", similar to /dev/null: the former is always at EOF, and the latter discards all the data written. They are useful to specify "no data" or to discard an output when working with stream-oriented APIs.
- {@link edu.emory.mathcs.util.io.CompressedOutputStream} and {@link edu.emory.mathcs.util.io.CompressedInputStream} provide data compression capabilities while maintaining strong flush semantics, that is, flushing causes all buffered data to be written out. Because of this feature, these classes can be used for request-response-based applications, e.g. as RMI or RPC transport. Note that standard {@link java.util.zip.ZipOutputStream} and {@link java.util.zip.GZIPOutputStream} lack this feature, and thus cannot be used as an RMI transport.