ByteArrayInputStream和ByteArrayOutputStream

1.ByteArrayInputStream和ByteArrayOutputStream简介

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

2.ByteArrayInputStream源码分析

package java.io;


public class ByteArrayInputStream extends InputStream {

    //字节缓冲区
    protected byte buf[];

    //当前读取字节的位置
    protected int pos;

    //标记字节的位置,如果没有标记,则为0
    protected int mark = 0;

    //记录字节数组的长度
    protected int count;

    //构造函数,初始化相关的参数
    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;
    }

    //返回当前pos位置上字节的值
    public synchronized int read() {
        //如果当前pos的位置的值超过了byte的最大的值,则和0xff与运算,获取正值
        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();
        }

        if (pos >= count) {
            return -1;
        }
     //获取当前缓冲的剩余大小
        int avail = count - pos;
     //如果写入b的长度大于当前缓冲区的大小,则更新写入的长度为当前缓冲区的大小
        if (len > avail) {
            len = avail;
        }
        if (len <= 0) {
            return 0;
        }
    //调用native方法把当前缓冲区的内容复制到b中
        System.arraycopy(buf, pos, b, off, len);
        pos += len;
        return len;
    }

    //跳过指定的字节大小,如果当前跳过的大小大于剩余的字节的数量,则跳过剩余字节的数量
    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;
    }

    //该字节流在内存中操作,不需要关闭
    public void close() throws IOException {
    }

}

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.示例代码

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class ByteTest {

    private static final String STRING1 = "成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。";

    public static void main(String[] args) {
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(STRING1.getBytes());

            byte[] buffer = new byte[STRING1.getBytes().length];
            byte[] bytes = new byte[1024];
            int count;
            int readCount=0;

            while((count=bis.read(bytes)) > 0)
            {
                System.arraycopy(bytes, 0, buffer, readCount, count);
                readCount += count;
            }
            System.out.println(new String(buffer,"utf-8"));

            System.out.println("============================");

            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);

            byte[] buffer2 = STRING1.getBytes();

            bos.write(buffer2,0,buffer2.length);

            //System.out.println(bos.toString("utf-8"));
            System.out.println(new String(bos.toByteArray(),"utf-8"));

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。
============================
成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值