Java Tutorial/File/OutputStream
Версия от 17:44, 31 мая 2010; (обсуждение)
Содержание
- 1 A null output stream. All data written to this stream is ignored.
- 2 Byte Counting OutputStream
- 3 Memory Byte Array OutputStream
- 4 Provides true Closable semantics ordinarily missing in a {@link java.io.ByteArrayOutputStream}.
- 5 Transfers all bytes that can be read from one stream to another stream.
- 6 Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when finished.
A null output stream. All data written to this stream is ignored.
/**
*
* JFreeReport : a free Java reporting library
*
*
* Project Info: http://reporting.pentaho.org/
*
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it 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.
*
* This library 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
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* NullOutputStream.java
* ------------
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*/
import java.io.IOException;
import java.io.OutputStream;
/**
* A null output stream. All data written to this stream is ignored.
*
* @author Thomas Morgner
*/
public class NullOutputStream extends OutputStream
{
/**
* Default constructor.
*/
public NullOutputStream ()
{
}
/**
* Writes to the stream (in this case, does nothing).
*
* @param i the value.
* @throws IOException if there is an I/O problem.
*/
public void write (final int i)
throws IOException
{
// no i wont do anything here ...
}
/**
* Writes to the stream (in this case, does nothing).
*
* @param bytes the bytes.
* @throws IOException if there is an I/O problem.
*/
public void write (final byte[] bytes)
throws IOException
{
// no i wont do anything here ...
}
/**
* Writes to the stream (in this case, does nothing).
*
* @param bytes the bytes.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @throws IOException if there is an I/O problem.
*/
public void write (final byte[] bytes, final int off, final int len)
throws IOException
{
// no i wont do anything here ...
}
}
Byte Counting OutputStream
import java.io.IOException;
import java.io.OutputStream;
/**
* Output stream that counts bytes written to it (but discards them).
*
* @author Jonathan Locke
*/
public final class ByteCountingOutputStream extends OutputStream
{
private long size;
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException
{
size++;
}
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte b[], int off, int len) throws IOException
{
size += len;
}
/**
* @return Number of bytes written to this stream
*/
public long size()
{
return size;
}
}
Memory Byte Array OutputStream
/**
*
* JFreeReport : a free Java reporting library
*
*
* Project Info: http://reporting.pentaho.org/
*
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it 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.
*
* This library 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
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* MemoryByteArrayOutputStream.java
* ------------
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*/
import java.io.IOException;
import java.io.OutputStream;
/**
* A string writer that is able to write large amounts of data. The original
* StringWriter contained in Java doubles its buffersize everytime the buffer
* overflows. This is nice with small amounts of data, but awfull for huge
* buffers.
*
* @author Thomas Morgner
*/
public class MemoryByteArrayOutputStream extends OutputStream {
private int maximumBufferIncrement;
private int cursor;
private byte[] buffer;
private byte[] singleIntArray;
/**
* Create a new character-stream writer whose critical sections will
* synchronize on the writer itself.
*/
public MemoryByteArrayOutputStream() {
this(4096, 65536);
}
/**
* Create a new character-stream writer whose critical sections will
* synchronize on the writer itself.
*/
public MemoryByteArrayOutputStream(final int bufferSize, final int maximumBufferIncrement) {
this.maximumBufferIncrement = maximumBufferIncrement;
this.buffer = new byte[bufferSize];
this.singleIntArray = new byte[1];
}
/**
* Write a portion of an array of characters.
*
* @param cbuf
* Array of characters
* @param off
* Offset from which to start writing characters
* @param len
* Number of characters to write
* @throws java.io.IOException
* If an I/O error occurs
*/
public synchronized void write(final byte[] cbuf, final int off, final int len)
throws IOException {
if (len < 0) {
throw new IllegalArgumentException();
}
if (off < 0) {
throw new IndexOutOfBoundsException();
}
if (cbuf == null) {
throw new NullPointerException();
}
if ((len + off) > cbuf.length) {
throw new IndexOutOfBoundsException();
}
ensureSize(cursor + len);
System.arraycopy(cbuf, off, this.buffer, cursor, len);
cursor += len;
}
/**
* Writes <code>b.length</code> bytes from the specified byte array to this
* output stream. The general contract for <code>write(b)</code> is that it
* should have exactly the same effect as the call <code>write(b, 0,
* b.length)</code>.
*
* @param b
* the data.
* @throws java.io.IOException
* if an I/O error occurs.
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(final byte[] b) throws IOException {
write(b, 0, b.length);
}
/**
* Writes the specified byte to this output stream. The general contract for
* <code>write</code> is that one byte is written to the output stream. The
* byte to be written is the eight low-order bits of the argument
* <code>b</code>. The 24 high-order bits of <code>b</code> are ignored.
* <p/> Subclasses of <code>OutputStream</code> must provide an
* implementation for this method.
*
* @param b
* the <code>byte</code>.
* @throws java.io.IOException
* if an I/O error occurs. In particular, an
* <code>IOException</code> may be thrown if the output stream has
* been closed.
*/
public synchronized void write(final int b) throws IOException {
this.singleIntArray[0] = (byte) (0xFF & b);
write(singleIntArray, 0, 1);
}
private void ensureSize(final int size) {
if (this.buffer.length >= size) {
return;
}
final int computedSize = (int) Math.min((this.buffer.length + 1) * 1.5, this.buffer.length
+ maximumBufferIncrement);
final int newSize = Math.max(size, computedSize);
final byte[] newBuffer = new byte[newSize];
System.arraycopy(this.buffer, 0, newBuffer, 0, cursor);
this.buffer = newBuffer;
}
/**
* Flush the stream. If the stream has saved any characters from the various
* write() methods in a buffer, write them immediately to their intended
* destination. Then, if that destination is another character or byte stream,
* flush it. Thus one flush() invocation will flush all the buffers in a chain
* of Writers and OutputStreams. <p/> If the intended destination of this
* stream is an abstraction provided by the underlying operating system, for
* example a file, then flushing the stream guarantees only that bytes
* previously written to the stream are passed to the operating system for
* writing; it does not guarantee that they are actually written to a physical
* device such as a disk drive.
*
* @throws java.io.IOException
* If an I/O error occurs
*/
public void flush() throws IOException {
if ((buffer.length - cursor) > 50000) {
System.out.println("WASTED: " + (buffer.length - cursor));
}
}
/**
* Close the stream, flushing it first. Once a stream has been closed, further
* write() or flush() invocations will cause an IOException to be thrown.
* Closing a previously-closed stream, however, has no effect.
*
* @throws java.io.IOException
* If an I/O error occurs
*/
public void close() throws IOException {
}
public synchronized byte[] toByteArray() {
final byte[] retval = new byte[cursor];
System.arraycopy(buffer, 0, retval, 0, cursor);
return retval;
}
public int getLength() {
return cursor;
}
public byte[] getRaw() {
if ((buffer.length - cursor) > 50000) {
System.out.println("WASTED: " + (buffer.length - cursor) + " Length: " + buffer.length);
}
return buffer;
}
}
Provides true Closable semantics ordinarily missing in a {@link java.io.ByteArrayOutputStream}.
/* 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.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
/* $Id: ClosableByteArrayOutputStream.java 2946 2009-03-22 17:44:48Z fredt $ */
/**
* @todo - finer-grained synchronization to reduce average
* potential monitor contention
*/
/**
* Provides true Closable semantics ordinarily missing in a
* {@link java.io.ByteArrayOutputStream}.
*
* Accumulates output in a byte array that automatically grows as needed.
*
* Data is retrieved using <tt>toByteArray()</tt>,
* <tt>toByteArrayInputStream()</tt>, <tt>toString()</tt> and
* <tt>toString(encoding)</tt>.
*
* {@link #close() Closing} a <tt>ClosableByteArrayOutputStream</tt> prevents
* further write operations, but all other operations may succeed until after
* the first invocation of {@link #free() free()}.
*
* Freeing a <tt>ClosableByteArrayOutputStream</tt> closes the stream and
* releases the internal buffer, preventing successful invocation of all
* operations, with the exception of <tt>size()<tt>, <tt>close()</tt>,
* <tt>isClosed()</tt>, <tt>free()</tt> and <tt>isFreed()</tt>.
*
* This class is especially useful when an accumulating output stream must be
* handed off to an extenal client under contract that the stream should
* exhibit true Closable behaviour in response both to internally tracked
* events and to client invocation of the <tt>OutputStream.close()</tt> method.
*
* @author boucherb@users
* @version 1.9.0
* @since 1.9.0
*/
public class ClosableByteArrayOutputStream extends OutputStream {
/**
* Data buffer.
*/
protected byte[] buf;
/**
* # of valid bytes in buffer.
*/
protected int count;
/**
* Whether this stream is closed.
*/
protected boolean closed;
/**
* Whether this stream is freed.
*/
protected boolean freed;
/**
* Creates a new output stream.
*
* The buffer capacity is initially 32 bytes, though its size increases
* if necessary.
*/
public ClosableByteArrayOutputStream() {
this(32);
}
/**
* Creates a new output stream with a buffer capacity of the specified
* <tt>size</tt>, in bytes.
*
* @param size the initial size.
* @exception IllegalArgumentException if size is negative.
*/
public ClosableByteArrayOutputStream(int size)
throws IllegalArgumentException {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size); // NOI18N
}
buf = new byte[size];
}
/**
* Writes the specified single byte.
*
* @param b the single byte to be written.
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #close() closed}.
*/
public synchronized void write(int b) throws IOException {
checkClosed();
int newcount = count + 1;
if (newcount > buf.length) {
buf = copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[count] = (byte) b;
count = newcount;
}
/**
* Writes the specified portion of the designated octet sequence.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #close() closed}.
*/
public synchronized void write(byte b[], int off,
int len) throws IOException {
checkClosed();
if ((off < 0) || (off > b.length) || (len < 0)
|| ((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
int newcount = count + len;
if (newcount > buf.length) {
buf = copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(b, off, buf, count, len);
count = newcount;
}
/**
* By default, does nothing.
*
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #close() closed}.
*/
public void flush() throws IOException {
checkClosed();
}
/**
* Writes the complete contents of this stream"s accumulated data to the
* specified output stream.
*
* The operation occurs as if by calling <tt>out.write(buf, 0, count)</tt>.
*
* @param out the output stream to which to write the data.
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #free() freed}.
*/
public synchronized void writeTo(OutputStream out) throws IOException {
checkFreed();
out.write(buf, 0, count);
}
/**
* Returns the current capacity of this stream"s data buffer.
*
* @return the length of the internal data array
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #free() freed}.
*/
public synchronized int capacity() throws IOException {
checkFreed();
return buf.length;
}
/**
* Resets the <tt>count</tt> field of this output stream to zero, so that
* all currently accumulated data is effectively discarded.
*
* Further write operations will reuse the allocated buffer space.
*
* @see #count
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #close() closed}.
*/
public synchronized void reset() throws IOException {
checkClosed();
count = 0;
}
/**
* Attempts to reduce this stream"s capacity to its current size.
*
* If the data buffer is larger than necessary to hold its current sequence
* of bytes, then it may be resized to become more space efficient.
* Calling this method may, but is not required to, affect the value
* returned by a subsequent call to the {@link #capacity()} method.
*
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #free() freed}.
*/
public synchronized void trimToSize() throws IOException {
checkFreed();
if (buf.length > count) {
buf = copyOf(buf, count);
}
}
/**
* Retrieves a copy of this stream"s accumated data, as a byte array.
*
* @return a copy of this stream"s accumated data, as a byte array.
* @see #size()
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #free() freed}.
*/
public synchronized byte[] toByteArray() throws IOException {
checkFreed();
return copyOf(buf, count);
}
/**
* Returns the current size of this stream"s accumated data.
*
* @return the value of the <tt>count</tt> field, which is the number
* of valid bytes in this output stream.
* @see #count
* @throws java.io.IOException never
*/
public synchronized int size() throws IOException {
return count;
}
/**
* Sets the size of this stream"s accumulated data.
*
* @param newSize the new size
* @throws ArrayIndexOutOfBoundsException if new size is negative
*/
public synchronized void setSize(int newSize) {
if (newSize < 0) {
throw new ArrayIndexOutOfBoundsException(newSize);
} else if (newSize > buf.length) {
buf = copyOf(buf, Math.max(buf.length << 1, newSize));
}
count = newSize;
}
/**
* Performs an effecient (zero-copy) conversion of the data accumulated in
* this output stream to an input stream.
*
* To ensure the future integrity of the resulting input stream, {@link
* #free() free} is invoked upon this output stream as a side-effect.
*
* @return an input stream representing this output stream"s accumulated
* data
* @throws java.io.IOException if an I/O error occurs.
* In particular, an <tt>IOException</tt> may be thrown
* if this output stream has been {@link #free() freed}.
*/
public synchronized ByteArrayInputStream toByteArrayInputStream()
throws IOException {
checkFreed();
ByteArrayInputStream inputStream = new ByteArrayInputStream(buf, 0,
count);
free();
return inputStream;
}
/**
* Converts this stream"s accumuated data into a string, translating bytes
* into characters according to the platform"s default character encoding.
*
* @return String translated from this stream"s accumuated data.
* @throws RuntimeException may be thrown if this output stream has been
* {@link #free() freed}.
*/
public synchronized String toString() {
try {
checkFreed();
} catch (IOException ex) {
throw new RuntimeException(ex.toString());
}
return new String(buf, 0, count);
}
/**
* Converts this stream"s accumuated data into a string, translating bytes
* into characters according to the specified character encoding.
*
* @return String translated from the buffer"s contents.
* @param enc a character-encoding name.
* @throws java.io.IOException may be thrown if this output stream has been
* {@link #free() freed}.
* @throws UnsupportedEncodingException If the named encoding is not
* supported.
*/
public synchronized String toString(String enc)
throws IOException, UnsupportedEncodingException {
checkFreed();
return new String(buf, 0, count, enc);
}
/**
* Closes this object for further writing.
*
* Other operations may continue to succeed until after the first invocation
* of {@link #free() free()}.
*
* @throws java.io.IOException if an I/O error occurs (default: never)
*/
public synchronized void close() throws IOException {
closed = true;
}
/**
* Retrieves whether this stream is closed.
* @return <tt>true</tt> if this stream is closed, else <tt>false</tt>
*/
public synchronized boolean isClosed() {
return closed;
}
/**
* Closes this object and releases the underlying buffer for
* garbage collection.
*
* @throws java.io.IOException if an I/O error occurs while closing
* this stream (default: never).
*/
public synchronized void free() throws IOException {
closed = true;
freed = true;
buf = null;
count = 0;
}
/**
* Retrieves whether this stream is freed.
*
* @return <tt>true</tt> if this stream is freed; else <tt>false</tt>.
*/
public synchronized boolean isFreed() {
return freed;
}
/**
* Tests whether this stream is closed.
*
* @throws java.io.IOException if this stream is closed.
*/
protected synchronized void checkClosed() throws IOException {
if (closed) {
throw new IOException("stream is closed."); // NOI18N
}
}
/**
* Tests whether this stream is freed.
*
* @throws java.io.IOException if this stream is freed.
*/
protected synchronized void checkFreed() throws IOException {
if (freed) {
throw new IOException("stream buffer is freed."); // NOI18N
}
}
/**
* Retrieves a copy of <tt>original</tt> with the given
* <tt>newLength</tt>.
*
* @param original the object to copy
* @param newLength the length of the copy
* @return copy of <tt>original</tt> with the given <tt>newLength</tt>
*/
protected byte[] copyOf(byte[] original, int newLength) {
byte[] copy = new byte[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
}
Transfers all bytes that can be read from one stream to another stream.
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Main {
/**
* Transfers all bytes that can be read from <tt>in</tt> to <tt>out</tt>.
*
* @param in The InputStream to read data from.
* @param out The OutputStream to write data to.
* @return The total number of bytes transfered.
*/
public static final long transfer(InputStream in, OutputStream out)
throws IOException
{
long totalBytes = 0;
int bytesInBuf = 0;
byte[] buf = new byte[4096];
while ((bytesInBuf = in.read(buf)) != -1) {
out.write(buf, 0, bytesInBuf);
totalBytes += bytesInBuf;
}
return totalBytes;
}
}
Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when finished.
/*
* 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.OutputStream;
/**
* @author Randall Hauch
*/
public class Main {
/**
* Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when
* finished.
*
* @param content the content to write to the stream; may be null
* @param stream the stream to which the content is to be written
* @throws IOException
* @throws IllegalArgumentException if the stream is null
*/
public static void write( String content,
OutputStream stream ) throws IOException {
boolean error = false;
try {
if (content != null) {
byte[] bytes = content.getBytes();
stream.write(bytes, 0, bytes.length);
}
} catch (IOException e) {
error = true; // this error should be thrown, even if there is an error flushing/closing stream
throw e;
} catch (RuntimeException e) {
error = true; // this error should be thrown, even if there is an error flushing/closing stream
throw e;
} finally {
try {
stream.flush();
} catch (IOException e) {
if (!error) throw e;
} finally {
try {
stream.close();
} catch (IOException e) {
if (!error) throw e;
}
}
}
}
}