Java8 I/O源码-ByteArrayInputStream
来源:互联网 发布:java小项目开发实例 编辑:程序博客网 时间:2024/05/18 12:02
前两篇文章Java8 I/O源码-InputStream和Java8 I/O源码-OutputStream简单介绍了IntputStream和OutputStream。本文将详细介绍ByteArrayInputStream的实现,拉开学习字节型输入流的序幕。
ByteArrayInputStream属于字节型输入流,包含一个内部缓冲区,该缓冲区包含从流中读取的字节。定义如下:
public class ByteArrayInputStream extends InputStream
outline
字段
构造方法
方法
构造方法
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;}
方法
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;}
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;}
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 {}
demo
import 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()); }}
总结
- 字节输入流必须提供返回下一个输入字节的read()方法。因为所有字节输入流的父类InputStream有这样一个抽象方法:public abstract int read()。
- ByteArrayInputStream 支持 mark/reset。
- ByteArrayInputStream的close方法无效,无法关闭此输入流。
想了解更多内容请参考
- Java8 I/O源码系列专栏-目录
(全文完)
原文地址:CSDN博客-潘威威的博客-http://blog.csdn.net/panweiwei1994/article/details/78145143
本文版权归作者所有,欢迎转载,但转载时请在文章明显位置给出原文作者名字(潘威威)及原文链接。请勿将本文用于任何商业用途。
阅读全文
1 0
- Java8 I/O源码-ByteArrayInputStream
- Java8 I/O源码-目录
- Java8 I/O源码-InputStream
- Java8 I/O源码-OutputStream
- Java8 I/O源码-ByteArrayOutputStream
- Java8 I/O源码-PrintWriter
- Java8 I/O源码-RandomAccessFile
- Java8 I/O源码-整体结构
- Java8 I/O源码-PipedInputStream与PipedOutputStream
- Java8 I/O源码-BufferedInputStream与BufferedOutputStream
- Java8 I/O源码-DataInputStream与DataOutputStream
- Java8 I/O源码-FileInputStream与FileOutputStream
- Java8 I/O源码-Reader与Writer
- Java8 I/O源码-CharArrayReader与CharArrayWriter
- Java8 I/O源码-PipedReader与PipedWriter
- Java8 I/O源码-BufferedReader与BufferedWriter
- Java8 I/O源码-FileReader和FileWriter
- Java8 I/O源码-InputStreamReader与OutputStreamWriter
- JSP小整理(二)
- KNN之手写数字识别
- GPU benchmark 编译问题
- KNN图像分类(基于python3.6)
- 【Android】实现一个弹簧(Spring)效果的动画
- Java8 I/O源码-ByteArrayInputStream
- String类2
- storm的acker机制
- 《黑天鹅》
- ubuntu 不能上网 报错 wired unmanaged
- JSP页面练习代码(一)
- 漫眼风尘
- 邻接表、构造有向图
- 在linux下编译java