• Java的I/O框架之ByteArrayInputStream和ByteArrayOutputStream


    ByteArrayInputStream和ByteArrayOutputStream用于处理字节流的输入输出,底层都是数组。

    ByteArrayInputStream

    构造方法
    ByteArrayInputStream(byte buf[])    使用数组buf[]构造新的数组流
    ByteArrayInputStream(byte buf[], int offset, int length)
    使用数组从下表offset开始,最多length长度的子数组来构造新的数组流
    
    synchronized int read() 
    synchronized int read(byte b[], int off, int len)
    synchronized long skip(long n)
    synchronized int available()
    boolean markSupported()
    void mark(int readAheadLimit)
    synchronized void reset()
    void close()
    

    源码解析:
    ByteArrayInputStream方法都用synchronized关键字标识,因此是线程安全的。

    ByteArrayInputStream具有成员变量protected byte buf[]用于存储数据,protected int pos标识了下一个读取的元素在数组中的下标,protected int mark用于标记索引,protected int count记录字节流的长度。

    int read() 返回下一个读取的字节(可以用(Char)强转为字节)
    int read(byte b[], int off, int len) 将字节流当前位置开始的len个字节写入数组,从数组的索引off位置开始写入
    long skip(long n) 跳过接下来的n个字节,即将当前索引pos设置为pos+n,或者当n大于count-pos时,跳过接下来的count-pos个字节
    int available() 返回字节流中剩余字节的数量
    boolean markSupported() 当前字节流是否支持mark/reset功能
    void mark(int readAheadLimit) 将mark设置为pos,readAheadLimit字段没有意义
    void reset() 将pos重置为mark
    void close() 关闭字节流

    public class ByteArrayExample {
    
       // 自定义常数5
    public static final int LEN=5;
    // 对应英文字母“abcddefghijklmnopqrsttuvwxyz”
    private static final byte[] ArrayLetters = {
            0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
    };
    
    public static void main(String[] args) throws IOException {
        String tmp = new String(ArrayLetters);
        System.out.println("ArrayLetters="+tmp);
    
        tesByteArrayInputStream() ;
    }
    
    /**
     * 测试ByteArrayInputStream
     */
    public static void tesByteArrayInputStream() throws IOException {
        ByteArrayInputStream bais=new ByteArrayInputStream(ArrayLetters);
    
        //读取下个字节
        int data=bais.read();
        System.out.println("当前字节为:"+ (char)data);
    
        //写入数据到数组b,写入起始位置为off,长度为len,从字节流下一字节开始写入
        byte b[]=new byte[LEN];
        bais.read(b,0,LEN);
        String tempb=new String(b);
        System.out.println("写入后的数组是"+tempb);
    
        //写入数组后,中间的元素已经被跳过了
        data=bais.read();
        System.out.println("当前字节为:"+ (char)data);
    
        //跳过两个字节
        long skipNum=bais.skip(2);
        data=bais.read();
        System.out.println("跳过的字节数是: "+skipNum+",当前字节是: "+ (char)data);
        //字节流可用字节数
        System.out.println("字节流可用字节数为: "+bais.available());
        //当前字节流是否支持mark/reset功能
        System.out.println("当前字节流是否支持mark/reset功能: "+bais.markSupported());
        //将当前pos作为mark
        bais.mark(0);
        data=bais.read();
        System.out.println("标记位置的字节是: "+ (char)data);
       //跳过LEN个字节,再reset到上次mark的位置
        bais.skip(LEN);
        bais.reset();
        data=bais.read();
        System.out.println("重置后的字节是: "+ (char)data);
    
        bais.close();
    }
    }
    

    ByteArrayOutputStream

    构造方法
    ByteArrayOutputStream() 构造一个容量为32的输出流,容量不够时数组字节流支持自动扩容
    ByteArrayOutputStream(int size) 构造一个容量为size的输出流
    
    
    void write(int b)
    void write(byte b[], int off, int len)
    void write(byte b[])
    void flush()
    void writeTo(OutputStream out)
    void reset()
    byte toByteArray()[]
    int size()
    String toString()
    String toString(String charsetName)
    close()
    

    源码解析:

    ByteArrayOutputStream方法都用synchronized关键字标识,因此是线程安全的。

    ByteArrayOutputStream具有缓冲数组 protected byte buf[]用于存储数据,protected int count记录的是存储素组buf的数据量。

    void ensureCapacity(int minCapacity) 保证存储数组的容量大于minCapacity,如果不满足的话,调用grow()方法扩大底层数组容量。

    void write(int b) 将int类型的b转换成byte,写入字节流

    void write(byte b[], int off, int len) j将数组中长度为len的数组写入到字节流数组中,写入的起始位置为off

    void writeTo(OutputStream out) 将字节输出流的所有数据写入到字节输出流out

    void reset() 重置当前字节数组输出流,将count置为0,使当前字节数组输出流可以被复用

    byte toByteArray()[] 将当前字节数组输出流数据存入一个新的byte数组

    int size() 返回当前字节数组的数据量

    String toString(String charsetName) 将当前字节数组装换成对应charsetName编码标准的字符串

    void flush() 流操作中,数据都是先写到缓冲区,然后再写入文件,flush()方法在close()方法之前调用,可以强制缓冲区的数据写入文件,防止close()方法关闭流后,缓冲区还没有写入文件的数据丢失

    public class ByteArrayExample {
    
       // 自定义常数5
    public static final int LEN=5;
    // 对应英文字母“abcddefghijklmnopqrsttuvwxyz”
    private static final byte[] ArrayLetters = {
            0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
    };
    
    public static void main(String[] args) throws IOException {
        String tmp = new String(ArrayLetters);
        System.out.println("ArrayLetters="+tmp);
        
        testByteArrayOutputStream();
    }
    
    /**
     * 测试ByteArrayOutPutStream
     */
    public static void testByteArrayOutputStream() throws IOException {
    
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
    
        //向字节数组输出流写入字节数组
        baos.write(ArrayLetters,0,LEN);
        System.out.println("写入ArrayLetters数组的五个元素后后,字节数组输入流为:"+baos.toString("utf-8"));
        //向字节数组写入f对应的int
        baos.write(0x66);
        System.out.println("写入f后,字节数组输入流为:"+baos.toString("utf-8"));
        //获得字节数组的长度
        System.out.println("字节数组的长度是: "+baos.size());
        //将字节流数组转换成数组
        byte[] b=baos.toByteArray();
        System.out.println("字节流转换成的数组: "+new String(b));
    
        // 将baos写入到另一个输出流中
        try {
            ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
            baos.writeTo((OutputStream)baos2);
            System.out.printf("baos2=%s
    ", baos2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        baos.flush();
        baos.close();
    }
    }
  • 相关阅读:
    页面控制多角度看Model1与Model2
    类型抽象Haxe3新增特性:抽象类型 Abstract Types
    hadoop配置Hadoop 2.0分布式环境搭建安装配置
    PostThreadMessage的应用
    禁用安全模式(2k,2k3,xp)
    如何使用内存池监视器 (Poolmon.exe) 解决内核模式内存泄漏
    WideCharToMultiByte,MultiByteToWideChar
    禁止stMgr.exe
    GetCurrentUserSid
    注册表修改大全
  • 原文地址:https://www.cnblogs.com/Simon-cat/p/9996613.html
Copyright © 2020-2023  润新知