[重学Java基础][Java IO流][Part.1]字符数组输入/输出流

[重学Java基础][Java IO流] [Part.1] 字符数组输入/输出流

CharArrayReader

概述

CharArrayReader字符数组输入流,继承了所有字符输入流的超类Reader类,是一个具体功能的子类,用于读取字符数组
此类是数据始终储存在内存中的节点流,也可称之为内存流
实际上并没有对外部数据源进行读入操作 直接采用内存中的数据
主要用于适配以字符输入流为参数的接口

源码分析

成员属性
public class CharArrayReader extends Reader {
    /** 字符数组缓冲流 */
    protected char buf[];

    /** 当前字符缓冲流 下一次读取的开始位置*/
    protected int pos;

    /** 在缓冲流中的被标记的位置. */
    protected int markedPos = 0;

    /**字符数组缓冲流的长度*/
    protected int count;

    ……
}

可以看到CharArrayReader存在四个成员属性
- 字符数组形式char buf[],实际上就是流的内容体
- 当前字符缓冲流下一次读取的开始位置int pos,每次读取就从pos标记的位置开始
- 在缓冲流中的被标记的位置 int markedPos 用户手动调用以保存当前读取位置
- 流内容长度int count
-

成员方法

这里写图片描述

成员方法一共有11个,主要的就是读取方法CharArrayReader,标记方法mark,重置方法reset

CharArrayReader构造方法有两个重载,一个直接读入字符数组char buf[]作为输入流,起始位置为0位,流的大小等于字符数组的大小。

 public CharArrayReader(char buf[]) {
            this.buf = buf;
            this.pos = 0;
            this.count = buf.length;
        }

另一个从指定位置读入入字符数组char buf[]作为输入流,起始位置为指定的offset,读入时从offset位置开始读入数据,读入的大小等于length,流的大小等于读入的length大小,但最大不超过字符数组buf的大小

public CharArrayReader(char buf[], int offset, int length) {
    if ((offset < 0) || (offset > buf.length) || (length < 0) ||
        ((offset + length) < 0)) {
        throw new IllegalArgumentException();
    }
    this.buf = buf;
    this.pos = offset;
    this.count = Math.min(offset + length, buf.length);
    this.markedPos = offset;
}

read方法 读取一个单字符 并移动游标 返回一个整型

public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (pos >= count)
                return -1;
            else
                return buf[pos++];
        }
    }

重载和CharArrayReader构造方法类似 加入了初始位置和读入大小

   public int read(char b[], int off, int len) throws IOException {
    ……
}

skip方法 跳过流的一部分内容 入参long n 跳过n大小的字符流内容 下次读入从n+1开始

   public long skip(long n) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (pos + n > count) {
                n = count - pos;
            }
            if (n < 0) {
                return 0;
            }
            pos += n;
            return n;
        }
    }

mark方法 标记当前流读取位置 配合reset方法使用 入参int readAheadLimit 无作用

  public void mark(int readAheadLimit) throws IOException {
        synchronized (lock) {
            ensureOpen();
            markedPos = pos;
        }
    }

reset方法 将流读取位置重置为标记的位置 配合mark方法使用

 public void reset() throws IOException {
        synchronized (lock) {
            ensureOpen();
            pos = markedPos;
        }
    }

代码示例

示例1

    char chs[]=new char[]  {'a','b','c','d','e','f','g','h','i','j','k','l','m','n'};

    //读入字符数组初始化CharArrayReader
    CharArrayReader charArrayReader=new CharArrayReader(chs);

    int i=0;
    //循环读取流内容并打印到控制台 -1结束
    while ((i=charArrayReader.read())!=-1)
    {
        System.out.printf("%s,",(char)i);
    }

- 运行结果

        a,b,c,d,e,f,g,h,i,j,k,l,m,n

示例2

      char chs[]=new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'};

        //读入字符数组初始化CharArrayReader
        CharArrayReader charArrayReader=new CharArrayReader(chs);

        int i=0;
        //读入字符流内容并循环输出前5位
        for(;i<=4;i++)
        {
            System.out.printf("%s ",(char)charArrayReader.read());
        }
        System.out.println();

        //保存当前读取位置 已读取5位 所以当前游标在f 下一位正常读入为f
        charArrayReader.mark(0);

        //跳过5个 所以读入游标移动到k
        charArrayReader.skip(5);

        for(i=0;i<=4;i++)
        {
            System.out.printf("%s ",(char)charArrayReader.read());
        }
        System.out.println();


        //重置读入游标到标记的位置
        charArrayReader.reset();

        for(i=0;i<=4;i++)
        {
            System.out.printf("%s ",(char)charArrayReader.read());
        }
        System.out.println();
  • 运行结果

    a b c d e 
    k l m n o 
    f g h i j 
    

CharArrayWriter

概述

CharArrayWriter字符数组输出流,继承了所有字符输出流的超类Writer类,是一个具体功能的子类,用于输出字符数组
此类是数据始终储存在内存中的节点流,也可称之为内存流
实际上并没有对外部数据汇进行写入操作 直接写入到内存中
主要用于适配以字符输出流为参数的接口

源码分析

成员属性
public class CharArrayWriter extends Writer {

        protected char buf[];

        protected int count;
}

字符串数组char buf[] 存储流内容体
流内容大小 int count

成员方法

这里写图片描述

可以看到主要也就是几个方法
可以初始化字符流数组大小的构造方法

   public CharArrayWriter() {
        this(32);
    }

    /**

    public CharArrayWriter(int initialSize) {
        if (initialSize < 0) {
            throw new IllegalArgumentException
            ("Negative initial  size: " + initialSize);
        }
        buf = new char[initialSize];
    }

不同入参的多重载append write方法

public void write(int c) {
    synchronized (lock) {
        int newcount = count + 1;
        if (newcount > buf.length) {
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
        }
        buf[count] = (char)c;
        count = newcount;
    }
}

public void write(char c[], int off, int len) {
    if ((off < 0) || (off > c.length) || (len < 0) ||
        ((off + len) > c.length) || ((off + len) < 0)) {
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return;
    }
    synchronized (lock) {
        int newcount = count + len;
        if (newcount > buf.length) {
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
        }
        System.arraycopy(c, off, buf, count, len);
        count = newcount;
    }
}


public void write(String str, int off, int len) {
    synchronized (lock) {
        int newcount = count + len;
        if (newcount > buf.length) {
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
        }
        str.getChars(off, off + len, buf, count);
        count = newcount;
    }
}

reset重置方法

public void reset() {
    count = 0;
}

示例代码

示例1

    CharArrayWriter charArrayWriter=new CharArrayWriter();

    charArrayWriter.write(97);
    charArrayWriter.write(98);
    charArrayWriter.write(99);

    System.out.println(charArrayWriter.toString());
  • 输出结果

    abc
    

示例2

    CharArrayWriter charArrayWriter=new CharArrayWriter();

    charArrayWriter.write("abcdefg",3,2);

    System.out.println(charArrayWriter.toString());

结语

其实这两个类和StringWriter StringReader两个字符串输入\输出流操作类很像
只不过一个流的入参是char型 另一个是String型

猜你喜欢

转载自blog.csdn.net/u011863951/article/details/80003869