• JavaIO -- Reader 和 Writer


    一、简介

      设计ReaderWriter继承层次结构主要是为了国际化。InputStreamOutStream流继承层次结构仅支持8位字节流,并不能很好的处理16位的Unicode字符。由于Unicode用于字符国际化(java本身的char也是16位的Unicode),所以添加了Reader和Writer继承层次结构就是为了所有的I/O操作中都支持Unicode。另外,字符流(Reader、Writer)比字节流(InputSteam、OutStream)更快。

      Reader 和 Writer对于字符流的输入和输出也是作为协议的存在。

    二、Reader(输入)

      基本和InputStream差不多,只不过它是操作字符流的。

    public abstract class Reader implements Readable, Closeable {
    
        //为了提高效率,字流对象可以使用除自身之外的对象来保护临界段。因此,子类应该在这个字段中使用对象,而不是this或同步方法。
        protected Object lock;
    
        protected Reader() {
            this.lock = this;
        }
    
        protected Reader(Object lock) {
            if (lock == null) {
                throw new NullPointerException();
            }
            this.lock = lock;
        }
    
        //
        public int read(java.nio.CharBuffer target) throws IOException {
            int len = target.remaining();
            char[] cbuf = new char[len];
            int n = read(cbuf, 0, len);
            if (n > 0)
                target.put(cbuf, 0, n);
            return n;
        }
    
        //读取单个字符
        public int read() throws IOException {
            char cb[] = new char[1];
            if (read(cb, 0, 1) == -1)
                return -1;
            else
                return cb[0];
        }
    
        //将字符读入数组
        public int read(char cbuf[]) throws IOException {
            return read(cbuf, 0, cbuf.length);
        }
    
        //从off开始,读取len长度的数组,读入数组中
        abstract public int read(char cbuf[], int off, int len) throws IOException;
    
        //可跳过字符数量的最大值
        private static final int maxSkipBufferSize = 8192;
    
        //存储跳过的字符数组
        private char skipBuffer[] = null;
    
        //跳过字符。返回实际跳过的字符数
        public long skip(long n) throws IOException {
            if (n < 0L)
                throw new IllegalArgumentException("skip value is negative");
            int nn = (int) Math.min(n, maxSkipBufferSize); //获取最小值
            synchronized (lock) {  //加锁
                if ((skipBuffer == null) || (skipBuffer.length < nn)) //数组不为空 || 数组长度小于跳过的字符数
                    skipBuffer = new char[nn];
                long r = n;
                while (r > 0) {
                    int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
                    if (nc == -1)
                        break;
                    r -= nc;
                }
                return n - r;
            }
        }
    
        //表示此流是否已准备好读取。
        public boolean ready() throws IOException {
            return false;
        }
    
        /表示该流是否支持mark()操作
        public boolean markSupported() {
            return false;
        }
    
        //标记当前流中的位置。
        public void mark(int readAheadLimit) throws IOException {
            throw new IOException("mark() not supported");
        }
    
        //重置
        public void reset() throws IOException {
            throw new IOException("reset() not supported");
        }
    
        //关闭流并释放与之关联的任何系统资源。
         abstract public void close() throws IOException;
    
    }

    三、Writer(输出)

    public abstract class Writer implements Appendable, Closeable, Flushable {
    
        //用于保存字符串和单个字符的写的临时缓冲区
        private char[] writeBuffer;
    
        //缓存区大小
        private static final int WRITE_BUFFER_SIZE = 1024;
    
     
        protected Object lock;
    
        protected Writer() {
            this.lock = this;
        }
    
        protected Writer(Object lock) {
            if (lock == null) {
                throw new NullPointerException();
            }
            this.lock = lock;
        }
    
        //写入一个字符
        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);
            }
        }
    
        //写入字符数组。
        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 {    //如果长度大于缓存区的长度,重新新建一个len长度的字符数组。但是不要永久地分配非常大的缓冲区。
                    cbuf = new char[len];
                }
                str.getChars(off, (off + len), cbuf, 0);//获取str字符串 从off开始,长度为len的字符串
                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;
    
    }
  • 相关阅读:
    springboot集成websocket
    验证regex表达式本身是否有问题
    Quartz Cron表达式 生成
    Cannot run program "python": CreateProcess error=2, 系统找不到指定的文件
    遇到多个构造器参数时,要考虑用构造器
    考虑使用静态工厂代替构造器
    idea自定义注释
    layui2.4.0前的table隐藏列
    002、获取屏幕大小
    001、关于TextView的一些小知识
  • 原文地址:https://www.cnblogs.com/FondWang/p/11826112.html
Copyright © 2020-2023  润新知