A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

ByteArrayInputStream属于字节型输入流,包含一个内部缓冲区,该缓冲区包含从流中读取的字节。定义如下:

public class ByteArrayInputStream extends InputStream
outline字段
字段
说明

protected byte buf[]
用来创建流的字节数组。

protected int pos
从输入流缓冲器中读取的下个字节的索引。

protected int mark = 0
流中的当前标记位置。

protected int count
字节流的长度
构造方法
方法
说明

public ByteArrayInputStream(byte buf[]) {…}
创建一个ByteArrayInputStream,使用buf作为其缓冲区数组。

public ByteArrayInputStream(byte buf[], int offset, int length) {…}
创建一个ByteArrayInputStream,使用buf作为其缓冲区数组,并指定标记位置和可以从缓冲区中可以读取字节的最大长度。
方法
方法
说明

public synchronized int read() {…}
从此输入流中读取下一个数据字节。

public synchronized int read(byte b[], int off, int len) {…}
将最多len个数据字节从此输入流读入byte数组。

public synchronized long skip(long n) {…}
从此输入流中跳过n个输入字节。

public synchronized int available() {…}
返回可从此输入流读取(或跳过)的剩余字节数。

public boolean markSupported() {…}
测试是否支持 mark/reset。

public void mark(int readAheadLimit) {…}
设置流中的当前标记位置。

public synchronized void reset() {…}
将缓冲区的位置重置为标记位置。

public void close() throws IOException {…}
关闭ByteArrayInputStream,此方法无效。
构造方法ByteArrayInputStream( byte buf[])/** * 创建一个ByteArrayInputStream,使用buf作为它的缓冲区数组。 *  * pos的初始值为0。 * count的初始值为buf的长度。 * * @param   buf   作为输入缓存区的字节数组。 */public ByteArrayInputStream(byte buf[]) {    // 使用buf作为缓冲区数组。    this.buf = buf;    // pos的初始值为0。    this.pos = 0;    // count的初始值为buf的长度。    this.count = buf.length;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
ByteArrayInputStream( byte buf[], int offset, int length)/** * 创建一个ByteArrayInputStream,使用buf作为它的缓冲区数组。 * pos的初始值为offset。 * count的初始值为offset+length和buf.length的最小值。 * 将mark的值设为offset。 * * @param   buf      作为输入缓存区的字节数组。 * @param   offset   缓冲区要读取的第一个字节的偏移量。 * @param   length   可以从缓冲区中读取的最大字节数。 */public ByteArrayInputStream(byte buf[], int offset, int length) {    this.buf = buf;    this.pos = offset;    //count的初始值为offset+length和buf.length的最小值    this.count = Math.min(offset + length, buf.length);    this.mark = offset;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
方法read()/** * 从此输入流中读取下一个数据字节。 * 返回一个 0 到 255 范围内的 int 字节值。 * 如果因为到达流末尾而没有可用的字节,则返回值-1。 *  * 此read方法不会阻塞。 * * @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为false,说明到达流末尾,这时没有可用的字节,返回-1;如果为true,此输入流中读取下一个数据字节。    return (pos < count) ? (buf[pos++] & 0xff) : -1;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
read( byte b[], int off, int len)/** * 从输入流中,读取最多len个字节到字节数组中。 *  * 如果pos大于等于count,则代表到达文件末尾,返回-1指示文件结束。 *  * 否则,读取的字节数k等于len和count-pos中的较小者。 * 如果k是正数,则以System.arraycopy执行的方式将buf[pos]到buf[pos+k-1]的字节复制到b[off]到b[off+k-1]中。 * 将值k与pos相加并返回k。 * * 此read方法不会阻塞。 * * @param   b     存储读入数据的缓冲区。 * @param   off   起始偏移量 * @param   len   读取的最大字节数。 * @return  读入缓冲区的总字节数,如果由于已到达流末尾而不再有数据,则返回-1。 * @exception  NullPointerException 如果b为null。 * @exception  IndexOutOfBoundsException 如果off为负,len为负,或者len大于b.length - off。 */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();    }    // 如果pos大于等于count,则代表到达文件末尾,返回-1指示文件结束。    if (pos >= count) {        return -1;    }    // 计算可以的字节数    int avail = count - pos;    // 重新计算读取的最大字节数    if (len > avail) {        len = avail;    }    //如果读取的最大字节数小于等于0,返回0    if (len <= 0) {        return 0;    }    // 从输入流中,读取len个字节到字节数组中。    System.arraycopy(buf, pos, b, off, len);    // pos后移n个位置    pos += len;    //读入缓冲区的总字节数    return len;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
skip( long n)/** * 从输入流中跳过n个输入字节。 *  * 如果已到达输入流末尾,则可能会跳过较少的字节。 * 实际跳过的字节数k等于n和count-pos中的较小者。 * 将值k与pos相加并返回k。 * * @param   n   要跳过的字节数。 * @return  实际跳过的字节数。 */public synchronized long skip(long n) {    // 计算可以跳过的最大字节数    long k = count - pos;    //计算实际可以跳过的字节数    if (n < k) {        k = n < 0 ? 0 : n;    }    // 跳过k个字节。    pos += k;    //返回实际跳过的字节。    return k;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
available()/** * 返回可从此输入流读取(或跳过)的剩余字节数。 *  * 返回值是 count - pos,不受阻塞地从此输入流读取(或跳过)的剩余字节数。 * * @return  不受阻塞地从此输入流读取(或跳过)的剩余字节数 */public synchronized int available() {    return count - pos;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
markSupported()/** * 测试此 InputStream 是否支持 mark/reset。  * ByteArrayInputStream 支持 mark/reset。 * * @since   JDK1.1 */public boolean markSupported() {    return true;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
mark( int readAheadLimit)/** * 设置流中的当前标记位置。 *  * 构造时默认将 ByteArrayInputStream 对象标记在位置零处。通过此方法可将其标记在缓冲区内的另一个位置处。 *  * 如果尚未设置标记,则标记值是传递给构造方法的偏移量(如果未提供偏移量,则标记值为 0)。 *  * readAheadLimit 对于此类没有意义。 * * @since   JDK1.1 */public void mark(int readAheadLimit) {    mark = pos;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
reset()/** * 将缓冲区的位置重置为标记位置。 *  * 除非已标记了另一个位置,或者在构造方法中指定了一个偏移量,否则该标记位置是 0。 */public synchronized void reset() {    pos = mark;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
close()/** * 关闭ByteArrayInputStream。 *  * 关闭方法无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。 */public void close() throws IOException {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
demoimport java.io.ByteArrayInputStream;import org.junit.Test;public class ByteArrayInputStreamTest {    byte[] buf = new byte[] { 2, 15, 67, -1, -9, 9 };    // 构造方法和read()    // 15,67,255,247,    // ********************    // 2,15,67,255,247,9,    @Test    public void test1() {        ByteArrayInputStream bais = new ByteArrayInputStream(buf, 1, 4);        int b;        while ((b = bais.read()) != -1) {            System.out.print(b + ",");        }        System.out.println("\n********************");        bais = new ByteArrayInputStream(buf);        while ((b = bais.read()) != -1) {            System.out.print(b + ",");        }    }    // skip()    // 15,67,255,247,9,    @Test    public void test2() {        ByteArrayInputStream bais = new ByteArrayInputStream(buf);        int b;        bais.skip(1);        while ((b = bais.read()) != -1) {            System.out.print(b + ",");        }    }    // available()    // 5,4,3,2,1,0,    @Test    public void test3() {        ByteArrayInputStream bais = new ByteArrayInputStream(buf);        while (bais.read() != -1) {            System.out.print(bais.available() + ",");        }    }    // markSupported()    // true    // 2    // 2    // ******************    // 15    @Test    public void test4() {        // 2, 15, 67, -1, -9, 9        // 默认标记值为0        ByteArrayInputStream bais = new ByteArrayInputStream(buf);        System.out.println(bais.markSupported());        System.out.println(bais.read());        bais.reset();        System.out.println(bais.read());        System.out.println("******************");        // mark()的参数没有意义        bais.mark(4);        while (bais.read() != -1) {        }        bais.reset();        System.out.println(bais.read());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
总结
  • 字节输入流必须提供返回下一个输入字节的read()方法。因为所有字节输入流的父类InputStream有这样一个抽象方法:public abstract int read()。
  • ByteArrayInputStream 支持 mark/reset。
  • ByteArrayInputStream的close方法无效,无法关闭此输入流。

想了解更多内容请参考

(全文完)

版权声明


1 个回复

倒序浏览

很不错,受教了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马