InputStream主要方法
public abstract int read ( )
public int read ( byte b[ ] )
public int read ( byte b[ ] , int off, int len)
public long skip ( long n)
public int available ( )
public void close ( )
public synchronized void mark ( int readlimit)
public synchronized void reset ( )
public boolean markSupported ( )
子类实现关系
源码实现
InputStream
public abstract class InputStream implements Closeable {
private static final int SKIP_BUFFER_SIZE = 2048 ;
private static byte [ ] skipBuffer;
public abstract int read ( ) throws IOException;
public int read ( byte b[ ] , int off, int len) throws IOException {
if ( b == null) {
throw new NullPointerException ( ) ;
} else if ( off < 0 || len < 0 || len > b. length - off) {
throw new IndexOutOfBoundsException ( ) ;
} else if ( len == 0 ) {
return 0 ;
}
int c = read ( ) ;
if ( c == - 1 ) { return - 1 ; }
b[ off] = ( byte ) c;
int i = 1 ;
try {
for ( ; i < len ; i++ ) {
c = read ( ) ;
if ( c == - 1 ) { break ; }
b[ off + i] = ( byte ) c;
}
} catch ( IOException ee) { }
return i;
}
public int read ( byte b[ ] ) throws IOException {
return read ( b, 0 , b. length) ;
}
public long skip ( long n) throws IOException {
long remaining = n;
int nr;
if ( skipBuffer == null)
skipBuffer = new byte [ SKIP_BUFFER_SIZE] ;
byte [ ] localSkipBuffer = skipBuffer;
if ( n <= 0 ) { return 0 ; }
while ( remaining > 0 ) {
nr = read ( localSkipBuffer, 0 , ( int ) Math. min ( SKIP_BUFFER_SIZE, remaining) ) ;
if ( nr < 0 ) { break ; }
remaining -= nr;
}
return n - remaining;
}
public int available ( ) throws IOException {
return 0 ;
}
public void close ( ) throws IOException { }
public synchronized void mark ( int readlimit) { }
public synchronized void reset ( ) throws IOException {
throw new IOException ( "mark/reset not supported" ) ;
}
public boolean markSupported ( ) {
return false ;
}
}
FilterInputStream
public class FilterInputStream extends InputStream {
protected volatile InputStream in;
protected FilterInputStream ( InputStream in) {
this . in = in;
}
public int read ( ) throws IOException {
return in. read ( ) ;
}
public int read ( byte b[ ] ) throws IOException {
return read ( b, 0 , b. length) ;
}
public int read ( byte b[ ] , int off, int len) throws IOException {
return in. read ( b, off, len) ;
}
public long skip ( long n) throws IOException {
return in. skip ( n) ;
}
public int available ( ) throws IOException {
return in. available ( ) ;
}
public void close ( ) throws IOException {
in. close ( ) ;
}
public synchronized void mark ( int readlimit) {
in. mark ( readlimit) ;
}
public synchronized void reset ( ) throws IOException {
in. reset ( ) ;
}
public boolean markSupported ( ) {
return in. markSupported ( ) ;
}
}
ByteArrayInputStream
public class ByteArrayInputStream extends InputStream {
protected byte buf[ ] ;
protected int pos;
protected int mark = 0 ;
protected int count;
public ByteArrayInputStream ( byte buf[ ] ) {
this . buf = buf;
this . pos = 0 ;
this . count = buf. length;
}
public ByteArrayInputStream ( byte buf[ ] , int offset, int length) {
this . buf = buf;
this . pos = offset;
this . count = Math. min ( offset + length, buf. length) ;
this . mark = offset;
}
public synchronized int read ( ) {
return ( pos < count) ? ( buf[ pos++ ] & 0xff ) : - 1 ;
}
public synchronized int read ( byte b[ ] , int off, int len) {
if ( b== null) {
throw new NullPointerException ( ) ;
} else if ( off < 0 || len < 0 || len > b. length- off) {
throw new IndexOutOfBoundsException ( ) ;
}
if ( pos >= count) { return - 1 ; }
if ( pos + len > count) { len = count - pos; }
if ( len <= 0 ) { return 0 ; }
System. arraycopy ( buf, pos, b, off, len) ;
pos += len;
return len;
}
public synchronized long skip ( long n) {
if ( pos + n > count) { n = count - pos; }
if ( n < 0 ) { return 0 ; }
pos += n;
return n;
}
public synchronized int available ( ) {
return count - pos;
}
public boolean markSupported ( ) {
return true ;
}
public void mark ( int readAheadLimit) {
mark = pos;
}
public synchronized void reset ( ) {
pos = mark;
}
public void close ( ) throws IOException {
}
}
BufferedInputStream
public class BufferedInputStream < FilterInputStream> extends FilterInputStream {
private static int defaultBufferSize = 8192 ;
protected volatile byte buf[ ] ;
protected int count;
protected int pos;
protected int markpos = - 1 ;
protected int marklimit;
private static final
AtomicReferenceFieldUpdater< BufferedInputStream, byte [ ] > bufUpdater =
AtomicReferenceFieldUpdater. newUpdater (
BufferedInputStream. class , byte [ ] . class , "buf" ) ;
private InputStream getInIfOpen ( ) throws IOException {
InputStream input = in;
if ( input == null) throw new IOException ( "Stream closed" ) ;
return input;
}
private byte [ ] getBufIfOpen ( ) throws IOException {
byte [ ] buffer = buf;
if ( buffer == null) throw new IOException ( "Stream closed" ) ;
return buffer;
}
public BufferedInputStream ( InputStream in) {
this ( in, defaultBufferSize) ;
}
public BufferedInputStream ( InputStream in, int size) {
super ( in) ;
if ( size <= 0 ) {
throw new IllegalArgumentException ( "Buffer size <= 0" ) ;
}
buf = new byte [ size] ;
}
private void fill ( ) throws IOException {
byte [ ] buffer = getBufIfOpen ( ) ;
if ( markpos < 0 )
pos = 0 ;
else if ( pos >= buffer. length)
if ( markpos > 0 ) {
int sz = pos - markpos;
System. arraycopy ( buffer, markpos, buffer, 0 , sz) ;
pos = sz;
markpos = 0 ;
} else if ( buffer. length >= marklimit) {
markpos = - 1 ;
pos = 0 ;
} else {
int nsz = pos * 2 ;
if ( nsz > marklimit)
nsz = marklimit;
byte nbuf[ ] = new byte [ nsz] ;
System. arraycopy ( buffer, 0 , nbuf, 0 , pos) ;
if ( ! bufUpdater. compareAndSet ( this , buffer, nbuf) ) {
throw new IOException ( "Stream closed" ) ;
}
buffer = nbuf;
}
count = pos;
int n = getInIfOpen ( ) . read ( buffer, pos, buffer. length - pos) ;
if ( n > 0 ) count = n + pos;
}
public synchronized int read ( ) throws IOException {
if ( pos >= count) {
fill ( ) ;
if ( pos >= count) return - 1 ;
}
return getBufIfOpen ( ) [ pos++ ] & 0xff ;
}
private int read1 ( byte [ ] b, int off, int len) throws IOException {
int avail = count - pos;
if ( avail <= 0 ) {
if ( len >= getBufIfOpen ( ) . length && markpos < 0 ) {
return getInIfOpen ( ) . read ( b, off, len) ;
}
fill ( ) ;
avail = count - pos;
if ( avail <= 0 ) return - 1 ;
}
int cnt = ( avail < len) ? avail : len;
System. arraycopy ( getBufIfOpen ( ) , pos, b, off, cnt) ;
pos += cnt;
return cnt;
}
public synchronized int read ( byte b[ ] , int off, int len)
throws IOException {
getBufIfOpen ( ) ;
if ( ( off | len | ( off + len) | ( b. length - ( off + len) ) ) < 0 ) {
throw new IndexOutOfBoundsException ( ) ;
} else if ( len == 0 ) {
return 0 ;
}
int n = 0 ;
for ( ; ; ) {
int nread = read1 ( b, off + n, len - n) ;
if ( nread <= 0 ) return ( n == 0 ) ? nread : n;
n += nread;
if ( n >= len) return n;
InputStream input = in;
if ( input != null && input. available ( ) <= 0 ) return n;
}
}
public synchronized long skip ( long n) throws IOException {
getBufIfOpen ( ) ;
if ( n <= 0 ) {
return 0 ;
}
long avail = count - pos;
if ( avail <= 0 ) {
if ( markpos < 0 ) return getInIfOpen ( ) . skip ( n) ;
fill ( ) ;
avail = count - pos;
if ( avail <= 0 ) return 0 ;
}
long skipped = ( avail < n) ? avail : n;
pos += skipped;
return skipped;
}
public synchronized int available ( ) throws IOException {
return getInIfOpen ( ) . available ( ) + ( count - pos) ;
}
public synchronized void mark ( int readlimit) {
marklimit = readlimit;
markpos = pos;
}
public synchronized void reset ( ) throws IOException {
getBufIfOpen ( ) ;
if ( markpos < 0 ) throw new IOException ( "Resetting to invalid mark" ) ;
pos = markpos;
}
public boolean markSupported ( ) {
return true ;
}
public void close ( ) throws IOException {
byte [ ] buffer;
while ( ( buffer = buf) != null) {
if ( bufUpdater. compareAndSet ( this , buffer, null) ) {
InputStream input = in;
in = null;
if ( input != null) input. close ( ) ;
return ;
}
}
}
}
PipedInputStream
public class PipedInputStream extends InputStream {
boolean closedByWriter = false ;
volatile boolean closedByReader = false ;
boolean connected = false ;
Thread readSide;
Thread writeSide;
protected static final int PIPE_SIZE = 1024 ;
protected byte buffer[ ] = new byte [ PIPE_SIZE] ;
protected int in = - 1 ;
protected int out = 0 ;
public PipedInputStream ( PipedOutputStream src) throws IOException {
connect ( src) ;
}
public PipedInputStream ( ) {
}
public void connect ( PipedOutputStream src) throws IOException {
src. connect ( this ) ;
}
protected synchronized void receive ( int b) throws IOException {
checkStateForReceive ( ) ;
writeSide = Thread. currentThread ( ) ;
if ( in == out) awaitSpace ( ) ;
if ( in < 0 ) {
in = 0 ;
out = 0 ;
}
buffer[ in++ ] = ( byte ) ( b & 0xFF ) ;
if ( in >= buffer. length) {
in = 0 ;
}
}
synchronized void receive ( byte b[ ] , int off, int len) throws IOException {
checkStateForReceive ( ) ;
writeSide = Thread. currentThread ( ) ;
int bytesToTransfer = len;
while ( bytesToTransfer > 0 ) {
if ( in == out) awaitSpace ( ) ;
int nextTransferAmount = 0 ;
if ( out < in) {
nextTransferAmount = buffer. length - in;
} else if ( in < out) {
if ( in == - 1 ) {
in = out = 0 ;
nextTransferAmount = buffer. length - in;
} else {
nextTransferAmount = out - in;
}
}
if ( nextTransferAmount > bytesToTransfer) nextTransferAmount = bytesToTransfer;
assert ( nextTransferAmount > 0 ) ;
System. arraycopy ( b, off, buffer, in, nextTransferAmount) ;
bytesToTransfer -= nextTransferAmount;
off += nextTransferAmount;
in += nextTransferAmount;
if ( in >= buffer. length) {
in = 0 ;
}
}
}
private void checkStateForReceive ( ) throws IOException {
if ( ! connected) {
throw new IOException ( "Pipe not connected" ) ;
} else if ( closedByWriter || closedByReader) {
throw new IOException ( "Pipe closed" ) ;
} else if ( readSide != null && ! readSide. isAlive ( ) ) {
throw new IOException ( "Read end dead" ) ;
}
}
private void awaitSpace ( ) throws IOException {
while ( in == out) {
checkStateForReceive ( ) ;
notifyAll ( ) ;
try {
wait ( 1000 ) ;
} catch ( InterruptedException ex) {
throw new java. io. InterruptedIOException ( ) ;
}
}
}
synchronized void receivedLast ( ) {
closedByWriter = true ;
notifyAll ( ) ;
}
public synchronized int read ( ) throws IOException {
if ( ! connected) {
throw new IOException ( "Pipe not connected" ) ;
} else if ( closedByReader) {
throw new IOException ( "Pipe closed" ) ;
} else if ( writeSide != null && ! writeSide. isAlive ( ) &&
! closedByWriter && ( in < 0 ) ) {
throw new IOException ( "Write end dead" ) ;
}
readSide = Thread. currentThread ( ) ;
int trials = 2 ;
while ( in < 0 ) {
if ( closedByWriter) {
return - 1 ;
}
if ( ( writeSide != null) && ( ! writeSide. isAlive ( ) ) && ( -- trials < 0 ) ) {
throw new IOException ( "Pipe broken" ) ;
}
notifyAll ( ) ;
try {
wait ( 1000 ) ;
} catch ( InterruptedException ex) {
throw new java. io. InterruptedIOException ( ) ;
}
}
int ret = buffer[ out++ ] & 0xFF ;
if ( out >= buffer. length) {
out = 0 ;
}
if ( in == out) {
in = - 1 ;
}
return ret;
}
public synchronized int read ( byte b[ ] , int off, int len) throws IOException {
if ( b == null) {
throw new NullPointerException ( ) ;
} else if ( off < 0 || len < 0 || len > b. length - off) {
throw new IndexOutOfBoundsException ( ) ;
} else if ( len == 0 ) {
return 0 ;
}
int c = read ( ) ;
if ( c < 0 ) {
return - 1 ;
}
b[ off] = ( byte ) c;
int rlen = 1 ;
while ( ( in >= 0 ) && ( -- len > 0 ) ) {
b[ off + rlen] = buffer[ out++ ] ;
rlen++ ;
if ( out >= buffer. length) {
out = 0 ;
}
if ( in == out) {
in = - 1 ;
}
}
return rlen;
}
public synchronized int available ( ) throws IOException {
if ( in < 0 )
return 0 ;
else if ( in == out)
return buffer. length;
else if ( in > out)
return in - out;
else
return in + buffer. length - out;
}
public void close ( ) throws IOException {
closedByReader = true ;
synchronized ( this ) {
in = - 1 ;
}
}
}