java io系列19之 CharArrayWriter(字符数组输出流)

本文摘抄至 : skywang12345

摘要 : 介绍了 CharArrayReader 其API 的函数意思,和通过示例介绍了大致的使用。注意 : 其write(int oneChar)的作用将int类型的oneChar换成char类型。flush()和close()为空方法,所以无效

本章,我们学习CharArrayWriter。学习时,我们先对CharArrayWriter有个大致了解,然后深入了解一下它的源码,最后通过示例来掌握它的用法。

CharArrayWriter 介绍


CharArrayReader 用于写入数据符,它继承于 Writer。操作的数据是以 字符为单位!

CharArrayWriter 函数列表

CharArrayWriter()
CharArrayWriter(int initialSize)

CharArrayWriter     append(CharSequence csq, int start, int end)
CharArrayWriter     append(char c)
CharArrayWriter     append(CharSequence csq)
void     close()
void     flush()
void     reset()
int     size()
char[]     toCharArray()
String     toString()
void     write(char[] buffer, int offset, int len)
void     write(int oneChar)
void     write(String str, int offset, int count)
void     writeTo(Writer out)

Writer和CharArrayWriter源码分析


Writer是CharArrayWriter的父类,我们先看看Writer的源码,然后再学CharArrayWriter的源码。

1. Writer源码分析(基于jdk1.7.40)

package java.io;

public abstract class Writer implements Appendable, Closeable, Flushable {

    //字符缓存数组、用于临时存放要写入字符输出流管道中的字符、  
    private char[] writeBuffer;

    //字符缓存数组的默认大小、  
    private static final int WRITE_BUFFER_SIZE = 1024;

    //用于同步针对此流的操作的对象、  
    protected Object lock;

    // 创建一个新的字符流、其关键部分将同步writer自身  
    protected Writer() {
        this.lock = this;
    }

    //创建一个新的字符流、其关键部分将同步obj自身  
    protected Writer(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

    //将一个字符以整数形式写入到缓存字符数组writerBuffer中 
    public void write(int c) throws IOException {
        synchronized (lock) {
            if (writeBuffer == null){
                writeBuffer = new char[WRITE_BUFFER_SIZE];
            }
            writeBuffer[0] = (char) c;
            write(writeBuffer, 0, 1);
        }
    }

    //将一个字符数组写入到writerBuffer中  
    public void write(char cbuf[]) throws IOException {
        write(cbuf, 0, cbuf.length);
    }

    //写入字符数组的某一部分。   
    abstract public void write(char cbuf[], int off, int len) throws IOException;

    //将一个字符串写入到当前流管道中 
    public void write(String str) throws IOException {
        write(str, 0, str.length());
    }

    // 将一个字符串的一部分写入到当前流的管道中 
    public void write(String str, int off, int len) throws IOException {
        synchronized (lock) {
            char cbuf[];
            if (len <= WRITE_BUFFER_SIZE) {
                if (writeBuffer == null) {
                    writeBuffer = new char[WRITE_BUFFER_SIZE];
                }
                cbuf = writeBuffer;
            } else {    // Don't permanently allocate very large buffers.
                cbuf = new char[len];
            }
            str.getChars(off, (off + len), cbuf, 0);
            write(cbuf, 0, len);
        }
    }

    //将一个字符有序数列追加到当前流管道中、返回当前流对象 
    public Writer append(CharSequence csq) throws IOException {
        if (csq == null)
            write("null");
        else
            write(csq.toString());
        return this;
    }

     //将一个字符有序数列的一部分追加到当前流管道中、返回当前流对象 
     public Writer append(CharSequence csq, int start, int end) throws IOException {
        CharSequence cs = (csq == null ? "null" : csq);
        write(cs.subSequence(start, end).toString());
        return this;
    }

    //将一个字符追加到当前流管道中、返回当前流对象 
    public Writer append(char c) throws IOException {
        write(c);
        return this;
    }


    abstract public void flush() throws IOException;

    abstract public void close() throws IOException;
}

2. CharArrayWriter 源码分析(基于jdk1.7.40)

package java.io;

import java.util.Arrays;


public
class CharArrayWriter extends Writer {

    // 字符数组缓冲
    protected char buf[];

    // 下一个字符的写入位置
    protected int count;

    // 构造函数:默认缓冲区大小是32
    public CharArrayWriter() {
        this(32);
    }

    // 构造函数:指定缓冲区大小是initialSize
    public CharArrayWriter(int initialSize) {
        if (initialSize < 0) {
            throw new IllegalArgumentException("Negative initial size: "
                                               + initialSize);
        }
        buf = new char[initialSize];
    }

    // 写入一个字符c到CharArrayWriter中
    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;
        }
    }

    // 写入字符数组c到CharArrayWriter中。off是“字符数组b中的起始写入位置”,len是写入的长度
    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;
        }
    }

    // 写入字符串str到CharArrayWriter中。off是“字符串的起始写入位置”,len是写入的长度
    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;
        }
    }

    // 将CharArrayWriter写入到“Writer对象out”中
    public void writeTo(Writer out) throws IOException {
        synchronized (lock) {
            out.write(buf, 0, count);
        }
    }

    // 将csq写入到CharArrayWriter中
    // 注意:该函数返回CharArrayWriter对象
    public CharArrayWriter append(CharSequence csq) {
        String s = (csq == null ? "null" : csq.toString());
        write(s, 0, s.length());
        return this;
    }

    // 将csq从start开始(包括)到end结束(不包括)的数据,写入到CharArrayWriter中。
    // 注意:该函数返回CharArrayWriter对象! 
    public CharArrayWriter append(CharSequence csq, int start, int end) {
        String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
        write(s, 0, s.length());
        return this;
    }

    // 将字符c追加到CharArrayWriter中!
    // 注意:它与write(int c)的区别。append(char c)会返回CharArrayWriter对象。
    public CharArrayWriter append(char c) {
        write(c);
        return this;
    }

    // 重置(清空buf、重头开始  )
    public void reset() {
        count = 0;
    }

    // 将CharArrayWriter的全部数据对应的char[]返回
    public char toCharArray()[] {
        synchronized (lock) {
            return Arrays.copyOf(buf, count);
        }
    }

    // 返回CharArrayWriter的大小
    public int size() {
        return count;
    }

    public String toString() {
        synchronized (lock) {
            return new String(buf, 0, count);
        }
    }

    public void flush() { }

    public void close() { }
}

说明:

CharArrayWriter实际上是将数据写入到“字符数组”中去。


  1. 通过 CharArrayWriter()创建的 CharArrayWriter 对应的字符数组大小是32。
  2. 通过 CharArrayWriter(int size) 创建的CharArrayWriter对应的字符数组大小是size。
  3. write(int oneChar) 的作用将 int类型的 oneChar 换成对应的 Char 类型,然后写入到 CharArrayWriter中。
  4. write(char[] buffer,int offset,int len)是将字符数组 buffer写入到输出流中,offset是从buffer中读取数据的起始偏移位置,len是读取的长度
  5. write(String str,int offset,int count)是将字符串 str写入到输入流中,offset是从str中读取数据的起始位置,count 是读取的长度
  6. append(char c)的作用是将 char类型的 c 写入到CharArrayWriter中,然后返回CharArrayWriter对象。
    注意:append(char c)与write(char c)都是将单个字符写入到CharArrayWriter中。它们的区别是 :

    1. append(cahr c)会返回CharArrayWriter对象
    2. 而write(char c)返回 void
  7. append(CharSequence csq,int start,int end)的作用将csq从start开始(包括)到end结束(不包括)的数据,写入到 CharArrayWriter中。
    注意:该函数返回CharArrayWriter对象!
  8. append(CharSequence csq)的作用将csq写入到CharArrayWriter中。
    注意:该函数返回CharArrayWriter对象!
  9. writeTo(OutputStream out) 将该“字符数组输出流”的数据全部写入到“输出流out”中。

示例代码


关于CharArrayWriter中API的详细用法,参考示例代码(CharArrayWriterTest.java):

public class CharArrayWriterTest {

    // 对应英文字母“abcdefghijklmnopqrstuvwxyz”
    private static final char[] ArrayLetters = new char[]
            {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

    public static void main(String[] args) {

        tesCharArrayWriter() ;
    }

    private static void tesCharArrayWriter() {

        // 创建CharArrayWriter字符流
        CharArrayWriter caw = new CharArrayWriter() ;

        try {
            //写入字符 “A” 
            caw.write('A') ;
//          caw.write(74);  // --- output ---- caw=AJBC
            // 写入字符串“BC”个字符
            caw.write("BC") ; //这里是写入String
            System.out.printf("caw=%s\n",caw);

            // 将ArrayLetters数组中从“3”开始的后5个字符(defgh)写入到caw中。
            caw.write(ArrayLetters, 3, 5) ;
            System.out.printf("caw=%s\n",caw);

            // (01) 写入字符0
            // (02) 然后接着写入“123456789”
            // (03) 再接着写入ArrayLetters中第8-12个字符(ijkl)
            caw.append('0')
                    .append("123456789")
                    //注意这里的 8-12 不是从 8开始,写入12个,而是写入 8-12 之间的数据
                        //以为数组是从 0 开始,所以为 [ ) 区间;
                    .append(String.valueOf(ArrayLetters),8,12) ;
             System.out.printf("caw=%s\n", caw);

            // 计算长度
             int size  =caw.size() ;
             System.out.printf("size=%d\n",size);

            // 转换成byte[]数组
             char[] buf = caw.toCharArray();
             System.out.printf("buf=%s\n",String.valueOf(buf));

            // 将caw写入到另一个输出流中
             CharArrayWriter caw2 = new CharArrayWriter();
             caw.writeTo(caw2);
             System.out.printf("caw2=%s\n",caw2);


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }


}

运行结果:

caw=ABC
caw=ABCdefgh
caw=ABCdefgh0123456789ijkl
size=22
buf=ABCdefgh0123456789ijkl
caw2=ABCdefgh0123456789ijkl

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值