File Input Output Java

/*
 * ImportStream.java Created Sep 9, 2010 by Andrew Butler, PSL
 */
//package prisms.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
/** Wraps a stream that has been exported to import the data in readable form */
public class ImportStream extends java.io.InputStream
{
  private java.io.InputStream theInput;
  /**
   * Wraps a stream with an import stream
   * 
   * @param wrap The exported stream to wrap
   * @throws IOException If an error occurs wrapping the stream
   */
  public ImportStream(java.io.InputStream wrap) throws IOException
  {
    java.util.zip.ZipInputStream zis;
    zis = new java.util.zip.ZipInputStream(ObfuscatingStream.unobfuscate(wrap));
    zis.getNextEntry();
    theInput = zis;
  }
  @Override
  public int read() throws IOException
  {
    return theInput.read();
  }
  @Override
  public int read(byte [] b) throws IOException
  {
    return theInput.read(b);
  }
  @Override
  public int read(byte [] b, int off, int len) throws IOException
  {
    return theInput.read(b, off, len);
  }
  @Override
  public long skip(long n) throws IOException
  {
    return theInput.skip(n);
  }
  @Override
  public int available() throws IOException
  {
    return theInput.available();
  }
  @Override
  public boolean markSupported()
  {
    return theInput.markSupported();
  }
  @Override
  public synchronized void mark(int readlimit)
  {
    theInput.mark(readlimit);
  }
  @Override
  public synchronized void reset() throws IOException
  {
    theInput.reset();
  }
  @Override
  public void close() throws IOException
  {
    theInput.close();
  }
}
/**
 * A utility class that allows for easy simple obfuscation of streamed data
 */
 class ObfuscatingStream
{
  private static final char [] HEX_CHARS = new char [] {'0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  /**
   * A class that obfuscates data as it is written to a binary stream
   */
  public static class ObfuscatingOutputStream extends OutputStream
  {
    private OutputStream theOS;
    private int theWarp;
    private int theCount;
    ObfuscatingOutputStream(OutputStream os)
    {
      theOS = os;
      theWarp = -1;
    }
    /**
     * @see java.io.OutputStream#write(int)
     */
    @Override
    public void write(int b) throws IOException
    {
      if(theWarp < 0)
      {
        theWarp = (int) (Math.random() * 8);
        theOS.write(theWarp);
      }
      int shift = (theWarp + theCount) % 8;
      theCount++;
      int toWrite = b & 0xff;
      toWrite = ((toWrite >> shift) | (toWrite << (8 - shift))) & 0xff;
      theOS.write(toWrite);
    }
  }
  /**
   * A class the unobfuscates data that was obfuscated by an {@link ObfuscatingOutputStream} as it
   * is read from an input stream
   */
  public static class UnobfuscatingInputStream extends InputStream
  {
    private InputStream theIS;
    private int theWarp;
    private int theCount;
    UnobfuscatingInputStream(InputStream is)
    {
      theIS = is;
      theWarp = -1;
    }
    /**
     * @see java.io.InputStream#read()
     */
    @Override
    public int read() throws IOException
    {
      if(theWarp < 0)
        theWarp = theIS.read();
      int read = theIS.read();
      if(read < 0)
        return read;
      int shift = (theWarp + theCount) % 8;
      theCount++;
      int ret = read & 0xff;
      ret = ((ret << shift) | (ret >> (8 - shift))) & 0xff;
      return ret;
    }
  }
  /**
   * Obfuscates an output stream
   * 
   * @param os The binary output stream for this utility to write obfuscated data to
   * @return The output stream for the calling method to write unobfuscated data
   */
  public static OutputStream obfuscate(OutputStream os)
  {
    return new ObfuscatingOutputStream(os);
  }
  /**
   * Unobfuscates an input stream
   * 
   * @param is The binary input stream for this utililty to read obfuscated data from
   * @return The input stream for the calling method to read the unobfuscated data from
   */
  public static InputStream unobfuscate(InputStream is)
  {
    return new UnobfuscatingInputStream(is);
  }
  /**
   * Obfuscates or unobfuscates the second command-line argument, depending on whether the first
   * argument starts with "o" or "u"
   * 
   * @param args Command-line arguments
   * @throws IOException If an error occurs obfuscating or unobfuscating
   */
  public static void main(String [] args) throws IOException
  {
    InputStream input = new ByteArrayInputStream(args[1].getBytes());
    StringBuilder toPrint = new StringBuilder();
    if(args[0].startsWith("o"))
    {
      ByteArrayOutputStream bytes = new ByteArrayOutputStream();
      OutputStream out = obfuscate(bytes);
      int read = input.read();
      while(read >= 0)
      {
        out.write(read);
        read = input.read();
      }
      byte [] receiptBytes = bytes.toByteArray();
      for(int b = 0; b < receiptBytes.length; b++)
      {
        int chr = (receiptBytes[b] + 256) % 256;
        toPrint.append(HEX_CHARS[chr >>> 4]);
        toPrint.append(HEX_CHARS[chr & 0xf]);
      }
    }
    else if(args[0].startsWith("u"))
    {
      input = unobfuscate(input);
      InputStreamReader reader = new InputStreamReader(input);
      int read = reader.read();
      while(read >= 0)
      {
        toPrint.append((char) read);
        read = reader.read();
      }
    }
    else
      throw new IllegalArgumentException("First argument must start with o or u");
    System.out.println(toPrint.toString());
  }
}