目录
简介
/**
* ByteArrayInputStream包含一个内部缓冲区,其中包含可以从流中读取的字节。
* 一个内部的计数器将跟踪read方法提供的下一个字节。
* <p>
* 关闭ByteArrayInputStream没有任何效果。
* 该类中的方法可以在流被关闭后调用,并且无需生成IOException。
*
* @author Arthur van Hoff
* @see java.io.StringBufferInputStream
* @since JDK1.0
*/
public
class ByteArrayInputStream extends InputStream
buf,pos,mark,count
/**
* 流的创建者提供的字节数组。
* 元素buf[0]到buf[count-1]是唯一可以从流中读取的字节;
* 元素buf[pos]是下一个要读取的字节。
*/
protected byte buf[];
/**
* 要从输入流缓冲区中读取的下一个字符的索引。
* 这个值应该总是非负的,并且不大于count的值。
* 下一个要从输入流缓冲区读取的字节是buf[pos]。
*/
protected int pos;
/**
* 流中当前标记的位置。
* ByteArrayInputStream对象在构造时默认被标记在位置0。
* 可以用mark()方法在缓冲区的另一个位置标记它们。
* reset()方法设置当前缓冲区位置到这个点。
* <p>
* 如果没有设置标记,则标记的值是传递给构造函数的offset
* (如果没有提供offset,则为0)。
*
* @since JDK1.1
*/
protected int mark = 0;
/**
* 比这个输入流的缓冲区中最后一个有效字符大一个的索引。
* 这个值应该总是非负的,并且不大于buf的长度。
* 它比buf中可以从输入流缓冲区中读取的最后一个字节的位置大1。
*/
protected int count;
两个构造函数
/**
* 创建ByteArrayInputStream,以便它使用buf作为它的缓冲区数组。
* 缓冲区数组未被复制。
* pos的初始值为0,,count的初始值是buf的长度。
*
* @param buf the input buffer.
*/
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
/**
* 创建ByteArrayInputStream,以便它使用buf作为它的缓冲区数组。
* pos的初始值为offset,count的初始值是offset+length和buf.length的最小值。
* 缓冲区数组未被复制。缓冲区的标记被设置为指定的offset。
*
* @param buf the input buffer.
* @param offset the offset in the buffer of the first byte to read.
* @param length the maximum number of bytes to read from the buffer.
*/
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;
}
两个read方法
/**
* 从这个输入流中读取下一个字节的数据。
* 字节值作为0到255之间的int类型返回。
* 如果因为已经到达流的末尾而没有可用的字节,则返回值-1。
* 这个读方法不能阻塞。
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream has been reached.
*/
public synchronized int read() {
// pos>=count时,返回-1
// 否则返回buf[pos] & 0xff
// buf[pos]是一个byte,对应8bit
// 0xff对应1111 1111
// 与运算后返回后8位,从byte变成int
// 最后pos++
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
/**
* 从这个输入流中读取最多len字节的数据到一个字节数组中。
* 如果pos等于count,则返回-1来表示文件的末尾。
* 否则,读取的字节数k等于len和count-pos中较小的一个。
*
* 如果k为正,则按照System.arraycopy执行的方式,
* buf[pos]到buf[pos+k-1]的字节复制到b[off]到b[off+k-1]中。
* pos被加上k,并且 k被返回。
* <p>
* 这个读方法不能阻塞。
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
*/
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;
}
int avail = count - pos;
if (len > avail) {
len = avail;
}
// len = min(len,count-pos)
if (len <= 0) {
return 0;
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
其余方法
/**
* 跳过这个输入流中的n个字节的输入。
* 如果到达了输入流的末尾,则跳过的字节可能会更少。
* 要跳过的实际字节数k等于较小的n,或者count-pos。
* 将值k添加到pos中并返回k。
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
*/
public synchronized long skip(long n) {
long k = count - pos;
if (n < k) {
k = n < 0 ? 0 : n;
}
// 对pos值操作即可
pos += k;
return k;
}
/**
* 返回可从此输入流读取(或跳过)的剩余字节数。
*
* 返回的值是count - pos,它是要从输入缓冲区读取的剩余字节数。
*
* @return the number of remaining bytes that can be read (or skipped
* over) from this input stream without blocking.
*/
public synchronized int available() {
return count - pos;
}
/**
* 测试这个输入流是否支持标记/重置。
* ByteArrayInputStream的markSupported的方法总是返回true。
*
* @since JDK1.1
*/
public boolean markSupported() {
return true;
}
/**
* 设置流中的当前标记位置。
* ByteArrayInputStream对象在构造时默认被标记在位置0。
* 它们可以用这种方法标记在缓冲区的另一个位置上。
* <p>
* 如果没有设置标记,则标记的值是传递给构造函数的偏移量
* (如果没有提供偏移量,则为0)。
*
* <p> 注意:这个类的readAheadLimit没有任何意义。
*
*
*
* @since JDK1.1
*/
public void mark(int readAheadLimit) {
mark = pos;
}
/**
* 将缓冲区重置到标记的位置。
* 除非在构造函数中标记了其他位置或指定了偏移量,否则标记的位置为0。
*/
public synchronized void reset() {
pos = mark;
}
/**
* 关闭ByteArrayInputStream没有任何效果。
* 该类中的方法可以在流被关闭后调用,而无需生成IOException。
*/
public void close() throws IOException {
}