ByteArrayInputStream和BufferedInputStream内部都维护着一个byte[]类型的数组,并且也都有mark(), reset(), skip()这样的方法,那么它们的区别是什么呢?通过看源码可以发现
1. 构造函数不同:
ByteArrayInputStream的构造函数
- public ByteArrayInputStream(byte buf[]) {
- this.buf = buf;
- this.pos = 0;
- this.count = buf.length;
- }
可以看到,ByteArrayInputStream是用外来的一个byte []类型的数组来对内部的数组进行初始化,而之后的操作,如mark(), reset(), skip(), read()也都是建立在这个数组之上,这个数组的大小将不再能变化。
BufferedInputStream的构造函数:
- 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];
- }
可以看到,BufferedInputStream的构造函数是从一个InputStream的实例构造而来,并且可以根据指定的size来初始化对应大小的内部数组。并且看内部函数fill()
- private void fill() throws IOException {
- byte[] buffer = getBufIfOpen();
- if (markpos < 0)
- pos = 0; /* no mark: throw away the buffer */
- else if (pos >= buffer.length) /* no room left in buffer */
- if (markpos > 0) { /* can throw away early part of the buffer */
- int sz = pos - markpos;
- System.arraycopy(buffer, markpos, buffer, 0, sz);
- pos = sz;
- markpos = 0;
- } else if (buffer.length >= marklimit) {
- markpos = -1; /* buffer got too big, invalidate mark */
- pos = 0; /* drop buffer contents */
- } else { /* grow buffer */
- 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)) {
- // Can't replace buf if there was an async close.
- // Note: This would need to be changed if fill()
- // is ever made accessible to multiple threads.
- // But for now, the only way CAS can fail is via close.
- // assert buf == null;
- throw new IOException("Stream closed");
- }
- buffer = nbuf; //内部数组指定为新建立的数组
- }
- count = pos;
- int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
- if (n > 0)
- count = n + pos;
- }
可知,BufferedInputStream内部的数组大小是可以更改的。
2. 第二个不同在于无论ByteArrayInputStream如何调用read,它都是在返回内部固定的数组中的数值。
如果当前位置超过了数组的count,那么返回-1
- public synchronized int read() {
- return (pos < count) ? (buf[pos++] & 0xff) : -1;
- }
而对于BufferedInputStream, 当其调用read()时候,如果当前的位置超过了数组的count,BufferedInputStream会去从底层的inputStream去读取新的数据,填充到内部数组中。
点击(此处)折叠或打开
- public synchronized int read() throws IOException {
- if (pos >= count) {
- fill(); //读取新的数据
- if (pos >= count)
- return -1;
- }
- return getBufIfOpen()[pos++] & 0xff;
- }
阅读(14543) | 评论(0) | 转发(1) |