Java Tutorial/File/InputStream

Материал из Java эксперт
Перейти к: навигация, поиск

An InputStream class that terminates the stream when it encounters a particular byte sequence.

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF 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.                                           *
 ****************************************************************/

import java.io.IOException;
import java.io.InputStream;
/**
 * An InputStream class that terminates the stream when it encounters a
 * particular byte sequence.
 *
 * @version 1.0.0, 24/04/1999
 */
public class CharTerminatedInputStream
    extends InputStream {
    /**
     * The wrapped input stream
     */
    private InputStream in;
    /**
     * The terminating character array
     */
    private int match[];
    /**
     * An array containing the last N characters read from the stream, where
     * N is the length of the terminating character array
     */
    private int buffer[];
    /**
     * The number of bytes that have been read that have not been placed
     * in the internal buffer.
     */
    private int pos = 0;
    /**
     * Whether the terminating sequence has been read from the stream
     */
    private boolean endFound = false;
    /**
     * A constructor for this object that takes a stream to be wrapped
     * and a terminating character sequence.
     *
     * @param in the <code>InputStream</code> to be wrapped
     * @param terminator the array of characters that will terminate the stream.
     *
     * @throws IllegalArgumentException if the terminator array is null or empty
     */
    public CharTerminatedInputStream(InputStream in, char[] terminator) {
        if (terminator == null) {
            throw new IllegalArgumentException("The terminating character array cannot be null.");
        }
        if (terminator.length == 0) {
            throw new IllegalArgumentException("The terminating character array cannot be of zero length.");
        }
        match = new int[terminator.length];
        buffer = new int[terminator.length];
        for (int i = 0; i < terminator.length; i++) {
            match[i] = (int)terminator[i];
            buffer[i] = (int)terminator[i];
        }
        this.in = in;
    }
    /**
     * Read a byte off this stream.
     *
     * @return the byte read off the stream
     * @throws IOException if an IOException is encountered while reading off the stream
     * @throws ProtocolException if the underlying stream returns -1 before the terminator is seen.
     */
    public int read() throws IOException {
        if (endFound) {
            //We"ve found the match to the terminator
            return -1;
        }
        if (pos == 0) {
            //We have no data... read in a record
            int b = in.read();
            if (b == -1) {
                //End of stream reached without seeing the terminator
                throw new java.net.ProtocolException("pre-mature end of data");
            }
            if (b != match[0]) {
                //this char is not the first char of the match
                return b;
            }
            //this is a match...put this in the first byte of the buffer,
            // and fall through to matching logic
            buffer[0] = b;
            pos++;
        } else {
            if (buffer[0] != match[0]) {
                //Maybe from a previous scan, there is existing data,
                // and the first available char does not match the
                // beginning of the terminating string.
                return topChar();
            }
            //we have a match... fall through to matching logic.
        }
        //MATCHING LOGIC
        //The first character is a match... scan for complete match,
        // reading extra chars as needed, until complete match is found
        for (int i = 0; i < match.length; i++) {
            if (i >= pos) {
                int b = in.read();
                if (b == -1) {
                    //end of stream found, so match cannot be fulfilled.
                    // note we don"t set endFound, because otherwise
                    // remaining part of buffer won"t be returned.
                    return topChar();
                }
                //put the read char in the buffer
                buffer[pos] = b;
                pos++;
            }
            if (buffer[i] != match[i]) {
                //we did not find a match... return the top char
                return topChar();
            }
        }
        //A complete match was made...
        endFound = true;
        return -1;
    }
    /**
     * Private helper method to update the internal buffer of last read characters
     *
     * @return the byte that was previously at the front of the internal buffer
     */
    private int topChar() {
        int b = buffer[0];
        if (pos > 1) {
            //copy down the buffer to keep the fresh data at top
            System.arraycopy(buffer, 1, buffer, 0, pos - 1);
        }
        pos--;
        return b;
    }
}





Compare the contents of two Streams to determine if they are equal or not.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.
 */
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
/** * Origin of code: Apache Avalon (Excalibur)
 * 
 * @author Peter Donald
 * @author Jeff Turner
 * @author Matthew Hawthorne
 * @author Stephen Colebourne
 * @author Gareth Davis
 * @version CVS $Revision$ $Date$*/
public class Main {
  /**
   * Compare the contents of two Streams to determine if they are equal or not.
   * 
   * This method buffers the input internally using <code>BufferedInputStream</code> if they are
   * not already buffered.
   * 
   * @param input1
   *            the first stream
   * @param input2
   *            the second stream
   * @return true if the content of the streams are equal or they both don"t exist, false
   *         otherwise
   * @throws NullPointerException
   *             if either input is null
   * @throws IOException
   *             if an I/O error occurs
   */
  public static boolean contentEquals(InputStream input1, InputStream input2) throws IOException
  {
    if (!(input1 instanceof BufferedInputStream))
    {
      input1 = new BufferedInputStream(input1);
    }
    if (!(input2 instanceof BufferedInputStream))
    {
      input2 = new BufferedInputStream(input2);
    }
    int ch = input1.read();
    while (-1 != ch)
    {
      int ch2 = input2.read();
      if (ch != ch2)
      {
        return false;
      }
      ch = input1.read();
    }
    int ch2 = input2.read();
    return (ch2 == -1);
  }
}





Compare two InputStream

/*
 * JBoss DNA (http://www.jboss.org/dna)
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * See the AUTHORS.txt file in the distribution for a full listing of 
 * individual contributors. 
 *
 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
 * is licensed to you under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * JBoss DNA 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
/**
 * @author Randall Hauch
 */
public class Main {
  /**
   * Compare two input stream
   * 
   * @param input1 the first stream
   * @param input2 the second stream
   * @return true if the streams contain the same content, or false otherwise
   * @throws IOException
   * @throws IllegalArgumentException if the stream is null
   */
  public static boolean isSame( InputStream input1,
                                InputStream input2 ) throws IOException {
      boolean error = false;
      try {
          byte[] buffer1 = new byte[1024];
          byte[] buffer2 = new byte[1024];
          try {
              int numRead1 = 0;
              int numRead2 = 0;
              while (true) {
                  numRead1 = input1.read(buffer1);
                  numRead2 = input2.read(buffer2);
                  if (numRead1 > -1) {
                      if (numRead2 != numRead1) return false;
                      // Otherwise same number of bytes read
                      if (!Arrays.equals(buffer1, buffer2)) return false;
                      // Otherwise same bytes read, so continue ...
                  } else {
                      // Nothing more in stream 1 ...
                      return numRead2 < 0;
                  }
              }
          } finally {
              input1.close();
          }
      } catch (IOException e) {
          error = true; // this error should be thrown, even if there is an error closing stream 2
          throw e;
      } catch (RuntimeException e) {
          error = true; // this error should be thrown, even if there is an error closing stream 2
          throw e;
      } finally {
          try {
              input2.close();
          } catch (IOException e) {
              if (!error) throw e;
          }
      }
  }
}





Convert InputStream to String

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Main {
  public static void main(String[] args) throws Exception {
    InputStream is = Main.class.getResourceAsStream("/data.txt");
    System.out.println(convertStreamToString(is));
  }
  public static String convertStreamToString(InputStream is) throws Exception {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
      sb.append(line + "\n");
    }
    is.close();
    return sb.toString();
  }
}





Counts down from a specified value the number of bytes actually read from the wrapped InputStream.

/* Copyright (c) 2001-2009, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.io.IOException;
import java.io.InputStream;
/**
 * Counts down from a specified value the number of bytes actually read
 * from the wrapped InputStream. 
 *
 * Returns minus one (-1) early from readXXX methods if the count
 * down reaches zero (0) before the end of the wrapped InputStream
 * is encountered. 
 *
 * This class is especially useful when a fixed number of bytes is to be read
 * from an InputStream that is in turn to be used as the source for an
 * {@link java.io.InputStreamReader InputStreamReader}.
 *
 * @author boucherb@users
 * @version 1.8.x
 * @since 1.8.x
 */
public final class CountdownInputStream extends InputStream {
    private long        count;
    private InputStream input;
    public CountdownInputStream(final InputStream is) {
        this.input = is;
    }
    public int read() throws IOException {
        if (this.count <= 0) {
            return -1;
        }
        final int b = this.input.read();
        if (b >= 0) {
            this.count--;
        }
        return b;
    }
    public int read(final byte[] buf) throws IOException {
        if (this.count <= 0) {
            return -1;
        }
        int len = buf.length;
        if (len > this.count) {
            len = (int) this.count;
        }
        final int r = this.input.read(buf, 0, len);
        if (r > 0) {
            this.count -= r;
        }
        return r;
    }
    public int read(final byte[] buf, final int off,
                    int len) throws IOException {
        if (this.count <= 0) {
            return -1;
        }
        if (len > this.count) {
            len = (int) this.count;
        }
        final int r = this.input.read(buf, 0, len);
        if (r > 0) {
            this.count -= r;
        }
        return r;
    }
    public void close() throws IOException {
        this.input.close();
    }
    public long getCount() {
        return this.count;
    }
    public void setCount(long count) {
        this.count = count;
    }
}





Creating a Manifest for a JAR File

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.jar.Manifest;
public class Main {
  public static void main(String[] argv) throws Exception {
    // Create a manifest from a file
    InputStream fis = new FileInputStream("manifestfile");
    Manifest manifest = new Manifest(fis);
    // Construct a string version of a manifest
    StringBuffer sbuf = new StringBuffer();
    sbuf.append("Manifest-Version: 1.0\n");
    sbuf.append("\n");
    sbuf.append("Name: javax/swing/JScrollPane.class\n");
    sbuf.append("Java-Bean: True\n");
    // Convert the string to a input stream
    InputStream is = new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8"));
    // Create the manifest
    manifest = new Manifest(is);
  }
}





Creating an input or output stream on a ByteBuffer

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public class Main {
  public static void main(String[] argv) throws Exception {
    ByteBuffer buf = ByteBuffer.allocate(10);
    OutputStream os = new ByteBufferBackedOutputStream(buf);
    InputStream is = new  ByteBufferBackedInputStream(buf);
  }
}
class ByteBufferBackedInputStream extends InputStream{
  
  ByteBuffer buf;
  ByteBufferBackedInputStream( ByteBuffer buf){
    this.buf = buf;
  }
  public synchronized int read() throws IOException {
    if (!buf.hasRemaining()) {
      return -1;
    }
    return buf.get();
  }
  public synchronized int read(byte[] bytes, int off, int len) throws IOException {
    len = Math.min(len, buf.remaining());
    buf.get(bytes, off, len);
    return len;
  }
}
class ByteBufferBackedOutputStream extends OutputStream{
  ByteBuffer buf;
  ByteBufferBackedOutputStream( ByteBuffer buf){
    this.buf = buf;
  }
  public synchronized void write(int b) throws IOException {
    buf.put((byte) b);
  }
  public synchronized void write(byte[] bytes, int off, int len) throws IOException {
    buf.put(bytes, off, len);
  }
  
}





EOLConvertingInputStream: InputStream which converts \r bytes not followed by \n and \n not preceded by \r to \r\n.

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF 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.                                           *
 ****************************************************************/

import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
/**
 * InputStream which converts <code>\r</code>
 * bytes not followed by <code>\n</code> and <code>\n</code> not 
 * preceded by <code>\r</code> to <code>\r\n</code>.
 */
public class EOLConvertingInputStream extends InputStream {
    /** Converts single "\r" to "\r\n" */
    public static final int CONVERT_CR   = 1;
    /** Converts single "\n" to "\r\n" */
    public static final int CONVERT_LF   = 2;
    /** Converts single "\r" and "\n" to "\r\n" */
    public static final int CONVERT_BOTH = 3;
    
    private PushbackInputStream in = null;
    private int previous = 0;
    private int flags = CONVERT_BOTH;
    
    /**
     * Creates a new <code>EOLConvertingInputStream</code>
     * instance converting bytes in the given <code>InputStream</code>.
     * The flag <code>CONVERT_BOTH</code> is the default.
     * 
     * @param in the <code>InputStream</code> to read from.
     */
    public EOLConvertingInputStream(InputStream in) {
        this(in, CONVERT_BOTH);
    }
    /**
     * Creates a new <code>EOLConvertingInputStream</code>
     * instance converting bytes in the given <code>InputStream</code>.
     * 
     * @param in the <code>InputStream</code> to read from.
     * @param flags one of <code>CONVERT_CR</code>, <code>CONVERT_LF</code> or
     *        <code>CONVERT_BOTH</code>.
     */
    public EOLConvertingInputStream(InputStream in, int flags) {
        super();
        
        this.in = new PushbackInputStream(in, 2);
        this.flags = flags;
    }
    /**
     * Closes the underlying stream.
     * 
     * @throws IOException on I/O errors.
     */
    @Override
    public void close() throws IOException {
        in.close();
    }
    
    /**
     * @see java.io.InputStream#read()
     */
    @Override
    public int read() throws IOException {
        int b = in.read();
        
        if (b == -1) {
            return -1;
        }
        
        if ((flags & CONVERT_CR) != 0 && b == "\r") {
            int c = in.read();
            if (c != -1) {
                in.unread(c);
            }
            if (c != "\n") {
                in.unread("\n");
            }
        } else if ((flags & CONVERT_LF) != 0 && b == "\n" && previous != "\r") {
            b = "\r";
            in.unread("\n");
        }
        
        previous = b;
        
        return b;
    }
}





Minimal InputStream subclass to fetch bytes form a String

/* Copyright (c) 2001-2009, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.io.IOException;
import java.io.InputStream;
/**
 * minimal InputStream subclass to fetch bytes form a String
 *
 * @author Fred Toussi (fredt@users dot sourceforge.net)
 * @version 1.7.0
 */
public class StringInputStream extends InputStream {
    protected int    strOffset  = 0;
    protected int    charOffset = 0;
    protected int    available;
    protected String str;
    public StringInputStream(String s) {
        str       = s;
        available = s.length() * 2;
    }
    public int read() throws java.io.IOException {
        if (available == 0) {
            return -1;
        }
        available--;
        char c = str.charAt(strOffset);
        if (charOffset == 0) {
            charOffset = 1;
            return (c & 0x0000ff00) >> 8;
        } else {
            charOffset = 0;
            strOffset++;
            return c & 0x000000ff;
        }
    }
    public int available() throws IOException {
        return available;
    }
}





Read and return the entire contents of the supplied InputStream.

/*
 * JBoss DNA (http://www.jboss.org/dna)
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * See the AUTHORS.txt file in the distribution for a full listing of 
 * individual contributors. 
 *
 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
 * is licensed to you under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * JBoss DNA 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author Randall Hauch
 */
public class Main {

  /**
   * Read and return the entire contents of the supplied {@link InputStream stream}. This method always closes the stream when
   * finished reading.
   * 
   * @param stream the stream to the contents; may be null
   * @return the contents, or an empty byte array if the supplied reader is null
   * @throws IOException if there is an error reading the content
   */
  public static byte[] readBytes( InputStream stream ) throws IOException {
      if (stream == null) return new byte[] {};
      byte[] buffer = new byte[1024];
      ByteArrayOutputStream output = new ByteArrayOutputStream();
      boolean error = false;
      try {
          int numRead = 0;
          while ((numRead = stream.read(buffer)) > -1) {
              output.write(buffer, 0, numRead);
          }
      } catch (IOException e) {
          error = true; // this error should be thrown, even if there is an error closing stream
          throw e;
      } catch (RuntimeException e) {
          error = true; // this error should be thrown, even if there is an error closing stream
          throw e;
      } finally {
          try {
              stream.close();
          } catch (IOException e) {
              if (!error) throw e;
          }
      }
      output.flush();
      return output.toByteArray();
  }
}





Read and return the entire contents of the supplied InputStream. This method always closes the stream when finished reading.

/*
 * JBoss DNA (http://www.jboss.org/dna)
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * See the AUTHORS.txt file in the distribution for a full listing of 
 * individual contributors. 
 *
 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
 * is licensed to you under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * JBoss DNA 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
/**
 * @author Randall Hauch
 */
public class Main {
  /**
   * Read and return the entire contents of the supplied {@link InputStream}. This method always closes the stream when finished
   * reading.
   * 
   * @param stream the streamed contents; may be null
   * @return the contents, or an empty string if the supplied stream is null
   * @throws IOException if there is an error reading the content
   */
  public static String read( InputStream stream ) throws IOException {
      return stream == null ? "" : read(new InputStreamReader(stream));
  }
  /**
   * Read and return the entire contents of the supplied {@link Reader}. This method always closes the reader when finished
   * reading.
   * 
   * @param reader the reader of the contents; may be null
   * @return the contents, or an empty string if the supplied reader is null
   * @throws IOException if there is an error reading the content
   */
  public static String read( Reader reader ) throws IOException {
      if (reader == null) return "";
      StringBuilder sb = new StringBuilder();
      boolean error = false;
      try {
          int numRead = 0;
          char[] buffer = new char[1024];
          while ((numRead = reader.read(buffer)) > -1) {
              sb.append(buffer, 0, numRead);
          }
      } catch (IOException e) {
          error = true; // this error should be thrown, even if there is an error closing reader
          throw e;
      } catch (RuntimeException e) {
          error = true; // this error should be thrown, even if there is an error closing reader
          throw e;
      } finally {
          try {
              reader.close();
          } catch (IOException e) {
              if (!error) throw e;
          }
      }
      return sb.toString();
  }
}





Reads at most certain bytes from input stream and returns them as a byte array.

/*
 * Copyright Aduna (http://www.aduna-software.ru/) (c) 1997-2006.
 *
 * Licensed under the Aduna BSD-style license.
 */
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Main {
  /**
   * Reads at most <tt>maxBytes</tt> bytes from the supplied input stream and
   * returns them as a byte array.
   *
   * @param in The InputStream supplying the bytes.
   * @param maxBytes The maximum number of bytes to read from the input
   * stream.
   * @return A byte array of size <tt>maxBytes</tt> if the input stream can
   * produce that amount of bytes, or a smaller byte containing all available
   * bytes from the stream otherwise.
   */
  public static final byte[] readBytes(InputStream in, int maxBytes)
    throws IOException
  {
    byte[] result = new byte[maxBytes];
    int bytesRead = in.read(result);
    int totalBytesRead = bytesRead;
    while (totalBytesRead < maxBytes && bytesRead >= 0) {
      // Read more bytes
      bytesRead = in.read(result, bytesRead, maxBytes - bytesRead);
      if (bytesRead > 0) {
        totalBytesRead += bytesRead;
      }
    }
    if (totalBytesRead < 0) {
      // InputStream at end-of-file
      result = new byte[0];
    }
    else if (totalBytesRead < maxBytes) {
      // Create smaller byte array
      byte[] tmp = new byte[totalBytesRead];
      System.arraycopy(result, 0, tmp, 0, totalBytesRead);
      result = tmp;
    }
    return result;
  }
}





Resettable File InputStream

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF 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.                                           *
 ****************************************************************/

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author  Federico Barbieri <fede@apache.org>
 */
public class ResettableFileInputStream
    extends InputStream
{
    protected static final int DEFAULT_BUFFER_SIZE = 1024;
    protected final String m_filename;
    protected int m_bufferSize;
    protected InputStream m_inputStream;
    protected long m_position;
    protected long m_mark;
    protected boolean m_isMarkSet;
    public ResettableFileInputStream( final File file )
        throws IOException
    {
        this( file.getCanonicalPath() );
    }
    public ResettableFileInputStream( final String filename )
        throws IOException
    {
        this( filename, DEFAULT_BUFFER_SIZE );
    }
    public ResettableFileInputStream( final String filename, final int bufferSize )
        throws IOException
    {
        m_bufferSize = bufferSize;
        m_filename = filename;
        m_position = 0;
        m_inputStream = newStream();
    }
    public void mark( final int readLimit )
    {
        m_isMarkSet = true;
        m_mark = m_position;
        m_inputStream.mark( readLimit );
    }
    public boolean markSupported()
    {
        return true;
    }
    public void reset()
        throws IOException
    {
        if( !m_isMarkSet )
        {
            throw new IOException( "Unmarked Stream" );
        }
        try
        {
            m_inputStream.reset();
        }
        catch( final IOException ioe )
        {
            try
            {
                m_inputStream.close();
                m_inputStream = newStream();
                m_inputStream.skip( m_mark );
                m_position = m_mark;
            }
            catch( final Exception e )
            {
                throw new IOException( "Cannot reset current Stream: " + e.getMessage() );
            }
        }
    }
    protected InputStream newStream()
        throws IOException
    {
        return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize );
    }
    public int available()
        throws IOException
    {
        return m_inputStream.available();
    }
    public void close() throws IOException
    {
        m_inputStream.close();
    }
    public int read() throws IOException
    {
        m_position++;
        return m_inputStream.read();
    }
    public int read( final byte[] bytes, final int offset, final int length )
        throws IOException
    {
        final int count = m_inputStream.read( bytes, offset, length );
        m_position += count;
        return count;
    }
    public long skip( final long count )
        throws IOException
    {
        m_position += count;
        return m_inputStream.skip( count );
    }
}





Using a Reader and a Writer, returns a String from an InputStream

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
/* Copyright (c) 1995-2000, The Hypersonic SQL Group.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the Hypersonic SQL Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * on behalf of the Hypersonic SQL Group.
 *
 *
 * For work added by the HSQL Development Group:
 *
 * Copyright (c) 2001-2009, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * Collection of static methods for converting strings between different formats
 * and to and from byte arrays.
 * 
 * 
 * Includes some methods based on Hypersonic code as indicated.
 * 
 * @author Thomas Mueller (Hypersonic SQL Group)
 * @author Fred Toussi (fredt@users dot sourceforge.net)
 * @version 1.9.0
 * @since 1.7.2
 */
public class Main {
  private static final byte[] HEXBYTES = { (byte) "0", (byte) "1", (byte) "2", (byte) "3",
      (byte) "4", (byte) "5", (byte) "6", (byte) "7", (byte) "8", (byte) "9", (byte) "a",
      (byte) "b", (byte) "c", (byte) "d", (byte) "e", (byte) "f" };

  /**
   * Using a Reader and a Writer, returns a String from an InputStream.
   *
   * Method based on Hypersonic Code
   *
   * @param x InputStream to read from
   * @throws IOException
   * @return a Java string
   */
  public static String inputStreamToString(InputStream x,
          String encoding) throws IOException {
      InputStreamReader in        = new InputStreamReader(x, encoding);
      StringWriter      writer    = new StringWriter();
      int               blocksize = 8 * 1024;
      char[]            buffer    = new char[blocksize];
      for (;;) {
          int read = in.read(buffer);
          if (read == -1) {
              break;
          }
          writer.write(buffer, 0, read);
      }
      writer.close();
      return writer.toString();
  }
}