zoukankan      html  css  js  c++  java
  • 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;
    
    }
  • 相关阅读:
    ZeptoLab Code Rush 2015
    UVa 10048 Audiophobia【Floyd】
    POJ 1847 Tram【Floyd】
    UVa 247 Calling Circles【传递闭包】
    UVa 1395 Slim Span【最小生成树】
    HDU 4006 The kth great number【优先队列】
    UVa 674 Coin Change【记忆化搜索】
    UVa 10285 Longest Run on a Snowboard【记忆化搜索】
    【NOIP2016提高A组模拟9.28】求导
    【NOIP2012模拟10.9】电费结算
  • 原文地址:https://www.cnblogs.com/FondWang/p/11826112.html
Copyright © 2011-2022 走看看