|
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;}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;}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;}markSupported()/** * 测试此 InputStream 是否支持 mark/reset。 * ByteArrayInputStream 支持 mark/reset。 * * @since JDK1.1 */public boolean markSupported() { return true;}mark( int readAheadLimit)/** * 设置流中的当前标记位置。 * * 构造时默认将 ByteArrayInputStream 对象标记在位置零处。通过此方法可将其标记在缓冲区内的另一个位置处。 * * 如果尚未设置标记,则标记值是传递给构造方法的偏移量(如果未提供偏移量,则标记值为 0)。 * * readAheadLimit 对于此类没有意义。 * * @since JDK1.1 */public void mark(int readAheadLimit) { mark = pos;}reset()/** * 将缓冲区的位置重置为标记位置。 * * 除非已标记了另一个位置,或者在构造方法中指定了一个偏移量,否则该标记位置是 0。 */public synchronized void reset() { pos = mark;}close()/** * 关闭ByteArrayInputStream。 * * 关闭方法无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。 */public void close() throws IOException {}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方法无效,无法关闭此输入流。
想了解更多内容请参考 (全文完) 版权声明
|