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\n", baos2);
    } catch (IOException e) {
        e.printStackTrace();
    }

    baos.flush();
    baos.close();
}
}

posted on 2018-11-21 17:50  ShoolyShooly  阅读(409)  评论(0编辑  收藏  举报

导航