(二)ByteArrayInputStream与ByteArrayOutputStream
来源:互联网 发布:java实现双向链表 编辑:程序博客网 时间:2024/05/29 07:07
ByteArrayInputStream总结:
- ByteArrayInputStream就是提供一个对字节数组的读接口,所以构造函数需要一个字节数组作为数据源。所有的读操作都是对读该数组。
- 因为需要对pos/count进行操作,为了保证多线程下的有效性,所有的read方法都进行了同步。
ByteArrayOutputStream总结:
- ByteArrayOutputStream提高一个对字节数组的写操作,内部将写入的数据放在一个字节数组中。
- 内部数组默认初始长度为32,也可以通过构造函数指定大小。
- writeTo(OutputStream out)可以将缓存的数据保存到真正的目的源中
- 当内部数组容量不足时,会自动扩容
使用场景:
在我的有限经验中很少用到,以下是我的一些理解。
1. 可以存储其他输入流数据,在关闭流之后,仍然可以操作数据(可以释放I/O资源)。
2. 需要对字符串进行字节操作时
ByteArrayInputStream源码
package java.io;public class ByteArrayInputStream extends InputStream { //输入源 protected byte buf[]; //下一个读取的数组下标 protected int pos; //记录要恢复的下标 protected int mark = 0; //输入源长度 protected int count; //这两个构造函数都需要传入一个字节数组,而这个数组就输入源,相关read()方法都是从这个数组读取数据 public ByteArrayInputStream(byte buf[]) { this.buf = buf; this.pos = 0; this.count = buf.length; } 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; } //byte转int,需要&0xff,为什么不返回byte呢?这个后面另讲 public synchronized int read() { return (pos < count) ? (buf[pos++] & 0xff) : -1; } 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(); } //数据全部读完返回-1 if (pos >= count) { return -1; } //计算最多可读字节长度 int avail = count - pos; if (len > avail) { len = avail; } if (len <= 0) { return 0; } System.arraycopy(buf, pos, b, off, len); pos += len; return len; } //跳过n个字节,在缓存数组长度范围内偏移指针即可 public synchronized long skip(long n) { long k = count - pos; if (n < k) { k = n < 0 ? 0 : n; } pos += k; return k; } //未读长度 public synchronized int available() { return count - pos; } //是否支持复位 public boolean markSupported() { return true; } //标记和复位也很简单,因为都是对数组操作 public void mark(int readAheadLimit) { mark = pos; } public synchronized void reset() { pos = mark; } //没有涉及底层I/O,不需要关闭 public void close() throws IOException { }}
ByteArrayOutputStream类源码
package java.io;import java.util.Arrays;public class ByteArrayOutputStream extends OutputStream { //输出源 protected byte buf[]; protected int count; public ByteArrayOutputStream() { this(32); } public ByteArrayOutputStream(int size) { if (size < 0) { throw new IllegalArgumentException("Negative initial size: " + size); } buf = new byte[size]; } private void ensureCapacity(int minCapacity) { // overflow-conscious code if (minCapacity - buf.length > 0) grow(minCapacity); } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = buf.length; int newCapacity = oldCapacity << 1; if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); buf = Arrays.copyOf(buf, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //这里write()方法最终都是输入到一个字节数组中,数组的长度是根据内容长度自动增长的 public synchronized void write(int b) { ensureCapacity(count + 1); buf[count] = (byte) b; count += 1; } public synchronized void write(byte b[], int off, int len) { if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0)) { throw new IndexOutOfBoundsException(); } ensureCapacity(count + len); System.arraycopy(b, off, buf, count, len); count += len; } public synchronized void writeTo(OutputStream out) throws IOException { out.write(buf, 0, count); } public synchronized void reset() { count = 0; } public synchronized byte toByteArray()[] { return Arrays.copyOf(buf, count); } public synchronized int size() { return count; } public synchronized String toString() { return new String(buf, 0, count); } public synchronized String toString(String charsetName) throws UnsupportedEncodingException { return new String(buf, 0, count, charsetName); } @Deprecated public synchronized String toString(int hibyte) { return new String(buf, hibyte, 0, count); } public void close() throws IOException { }}
ByteArrayOutputStream缓存数组自动扩容方法
//判断是否需要扩容,每次调用write方法都会调用该方法进行判断 //minCapacity:最小容量,一般是count+len(len为写入长度) private void ensureCapacity(int minCapacity) { // overflow-conscious code if (minCapacity - buf.length > 0) grow(minCapacity); } //数组最大长度。为什么要Integer.MAX_VALUE - 8? //部分虚拟机需要在数组中保存相关信息,占用一定空间 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //真正的扩容函数 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = buf.length; int newCapacity = oldCapacity << 1;//左移1位就是2倍大小 if (newCapacity - minCapacity < 0)//取最小,不要浪费空间 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0)//超过规定大小了怎么办 newCapacity = hugeCapacity(minCapacity); buf = Arrays.copyOf(buf, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow//count+len溢出了,超过Integer.MAX_VALUE throw new OutOfMemoryError(); //实在没办法了,最多就给Integer.MAX_VALUE,什么头部信息的不管了 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
参考文章
Java io系列
阅读全文
0 0
- (二)ByteArrayInputStream与ByteArrayOutputStream
- java.io ByteArrayInputStream与ByteArrayOutputStream理解(二)
- ByteArrayInputStream与ByteArrayOutputStream类
- ByteArrayInputStream与ByteArrayOutputStream
- java.ByteArrayInputStream与ByteArrayOutputStream
- ByteArrayInputStream与ByteArrayOutputStream详解
- ByteArrayinputStream与ByteArrayOutputStream,printStream
- 5 ByteArrayInputStream 与 ByteArrayOutputStream类
- java.ByteArrayInputStream与ByteArrayOutputStream理解
- java.ByteArrayInputStream与ByteArrayOutputStream浅谈
- ByteArrayInputStream ByteArrayOutputStream(char,String)
- ByteArrayOutputStream&ByteArrayInputStream
- ByteArrayOutputStream, ByteArrayInputStream
- java.ByteArrayInputStream与ByteArrayOutputStream再次理解
- java.ByteArrayInputStream与ByteArrayOutputStream再次理解
- 黑马程序员 IO流 ByteArrayInputStream与ByteArrayOutputStream
- java.ByteArrayInputStream与ByteArrayOutputStream再次理解
- 内存虚拟文件(ByteArrayOutputStreamとByteArrayInputStream)
- 使用EventBus轻松实现组件间通信
- 最短路径
- top free命令真的能得到实际内存使用状况吗?
- 测试方法
- Node+OCR(图像文字识别)
- (二)ByteArrayInputStream与ByteArrayOutputStream
- eclipse中把Java工程修改成web工程 最简单
- Google Data Binding Library 谷歌官方数据绑定库(三)在引用布局中使用数据绑定
- RecyclerView的自定义分割线
- inetaddress
- $.ajax()方法详解
- JAVA动态加载properties,不需要重启服务器
- 初识MapReduce
- Android MVP框架解析