博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java(jdk1.7) IO系列02之ByteArrayInputStream和ByteArrayOutputStream解析
阅读量:4341 次
发布时间:2019-06-07

本文共 7390 字,大约阅读时间需要 24 分钟。

1.ByteArrayInputStream和ByteArrayOutputStream简介

 ByteArrayInputStream是字节数组输入流,继承InputStream,它里面维护一个缓冲区,也就是一个byte类型的数组,通过一个计数器pos来实现对字节数组的读取。与之相对应的ByteArrayOutputStream是字节数组输出流,继承自OutputStream,它里面也维护一个缓冲区,通过一个计数器count来实现对字节数组的操作。具体实现如下

2.ByteArrayInputStream源码分析

1 package java.io;  2   3   4 public class ByteArrayInputStream extends InputStream {  5   6     //字节缓冲区  7     protected byte buf[];  8   9     //当前读取字节的位置 10     protected int pos; 11  12     //标记字节的位置,如果没有标记,则为0 13     protected int mark = 0; 14  15     //记录字节数组的长度 16     protected int count; 17  18     //构造函数,初始化相关的参数 19     public ByteArrayInputStream(byte buf[]) { 20         this.buf = buf; 21         this.pos = 0; 22         this.count = buf.length; 23     } 24  25     //根据传入的字节数组的起始位置和读取长度的构造函数 26     public ByteArrayInputStream(byte buf[], int offset, int length) { 27         this.buf = buf; 28         this.pos = offset; 29         this.count = Math.min(offset + length, buf.length); 30         this.mark = offset; 31     } 32  33     //返回当前pos位置上字节的值 34     public synchronized int read() { 35         //如果当前pos的位置的值超过了byte的最大的值,则和0xff与运算,获取正值 36         return (pos < count) ? (buf[pos++] & 0xff) : -1; 37     } 38  39     //把当前字节流里面的数据读取到传入的字节数组中 40     public synchronized int read(byte b[], int off, int len) { 41         if (b == null) { 42             throw new NullPointerException(); 43         } else if (off < 0 || len < 0 || len > b.length - off) { 44             throw new IndexOutOfBoundsException(); 45         } 46  47         if (pos >= count) { 48             return -1; 49         } 50      //获取当前缓冲的剩余大小 51         int avail = count - pos; 52      //如果写入b的长度大于当前缓冲区的大小,则更新写入的长度为当前缓冲区的大小 53         if (len > avail) { 54             len = avail; 55         } 56         if (len <= 0) { 57             return 0; 58         } 59     //调用native方法把当前缓冲区的内容复制到b中 60         System.arraycopy(buf, pos, b, off, len); 61         pos += len; 62         return len; 63     } 64  65     //跳过指定的字节大小,如果当前跳过的大小大于剩余的字节的数量,则跳过剩余字节的数量 66     public synchronized long skip(long n) { 67         long k = count - pos; 68         if (n < k) { 69             k = n < 0 ? 0 : n; 70         } 71  72         pos += k; 73         return k; 74     } 75  76     //返回当前还有多少个字节可读取 77     public synchronized int available() { 78         return count - pos; 79     } 80  81    //是否支持标记 82     public boolean markSupported() { 83         return true; 84     } 85  86     //把字节流的标记位标记到当前流读取的位置,不支持传入的参数 87     public void mark(int readAheadLimit) { 88         mark = pos; 89     } 90  91     //重置当前流到标记的位置开始读取 92     public synchronized void reset() { 93         pos = mark; 94     } 95  96     //该字节流在内存中操作,不需要关闭 97     public void close() throws IOException { 98     } 99 100 }

 

3.ByteArrayOutputStream源码分析

package java.io;import java.util.Arrays;public class ByteArrayOutputStream extends OutputStream {   //缓冲区    protected byte buf[];    //当前缓冲区存储字节的数量    protected int count;    //初始化默认的字节流的缓冲大小为32    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 void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = buf.length;        int newCapacity = oldCapacity << 1;        //最小扩容为原来的一倍        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity < 0) {//超过Integer的大小,则变为负数            if (minCapacity < 0) // overflow                throw new OutOfMemoryError();            newCapacity = Integer.MAX_VALUE;        }        buf = Arrays.copyOf(buf, newCapacity);    }    //写入一个字节到字节流数组    public synchronized void write(int b) {        ensureCapacity(count + 1);        buf[count] = (byte) b;        count += 1;    }   //把传入的字节数组b从off开始写入len的长度到当前字节流数组    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;    }    //把一个outputStream中存储的数据写入到当前字节流数组    public synchronized void writeTo(OutputStream out) throws IOException {        out.write(buf, 0, count);    }   //重置字节流数组的读取的位置为0    public synchronized void reset() {        count = 0;    }    //把字节流转换成字节数组    public synchronized byte toByteArray()[] {        return Arrays.copyOf(buf, count);    }    //返回当前字节流数组读取的位置    public synchronized int size() {        return count;    }    //根据默认的字节编码来把字节流转换成string    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 {    }}

 

4.示例代码

 
1 package com.zwc.io.test; 2  3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.IOException; 6 import java.io.UnsupportedEncodingException; 7  8 public class TestByteArray { 9     private static final String STRING1 = "好好学习,天天向上,good good study, day day up";10     public static void main(String[] args) throws Exception {11         testByteArrayInputStream();12         System.out.println("=====================");13         testByteArrayOutputStream();14         15     }16     private static void testByteArrayOutputStream() throws Exception{17         ByteArrayOutputStream bos = new ByteArrayOutputStream(66);18         bos.write(STRING1.getBytes("utf-8"));19         System.out.println(bos.size());20         System.out.println(bos.toString("utf-8"));21         byte[] bytes = bos.toByteArray();22         bos.reset();//重置当前字节输出流的位置到开始位置23         bos.write(bytes);//重新把字节数组写入到bos中24         System.out.println(bos.toString("utf-8"));25         26     }27     private static void testByteArrayInputStream()28             throws UnsupportedEncodingException, IOException {29         byte[] bytes = STRING1.getBytes("utf-8");30         ByteArrayInputStream bis = new ByteArrayInputStream(bytes);31         if(bis.markSupported()) {32             bis.mark(0);//表示从0的位置开始标记,0实际上没有意义,只会从当前流的cout位置标记,也就是把mark = cout33         }34         bis.skip(30);//跳过30个字节35         byte[] out = new byte[bis.available()];36         bis.read(out);37         System.out.println(new String(out, "utf-8"));38         bis.reset();//回到0标记的位置39         out = new byte[bis.available()];//重新初始化字节数组40         bis.read(out);41         System.out.println(new String(out, "utf-8"));42     }43 }
 

 

 

 

执行结果:

good good study, day day up

好好学习,天天向上,good good study, day day up
=====================
57
好好学习,天天向上,good good study, day day up
好好学习,天天向上,good good study, day day up

 

转载于:https://www.cnblogs.com/flyinjava/p/6446069.html

你可能感兴趣的文章
Div居中,Div里的内容居中
查看>>
神州通,我看行---K2用户交流会华南站
查看>>
C# winform 中 TabControl 动态显示 TabPage
查看>>
SVM
查看>>
Projects_ILs Parameterization
查看>>
wpf首次项目开发总结之缺陷
查看>>
SQL Server使用ROW_NUMBER进行快速分页查询
查看>>
sql server 行转列
查看>>
矫正自己的机器人---39
查看>>
关于WCF服务寄宿的一些小细节
查看>>
多线程知识点整理
查看>>
字符串排成字典序,字符串数组
查看>>
Spring 基于注解的配置
查看>>
C#进行Visio二次开发之Visio模具制作(1)
查看>>
Winform开发框架之存储过程的支持--存储过程的实现和演化提炼(2)
查看>>
js公有、私有、静态属性和方法的区别
查看>>
Java NetWork笔记
查看>>
sys,time,pickle,json
查看>>
全排列的几种算法
查看>>
python之Django学习笔记(四)---数据模型(SQLITE3)以及相关操作
查看>>