zoukankan      html  css  js  c++  java
  • Reader 与 Guava MultiReader

    Reader是Java IO体系里字符处理读取流的基本类,代码如下

    /*
     * %W% %E%
     *
     * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     */
    
    package java.io;
    
    
    /**
     * Abstract class for reading character streams.  The only methods that a
     * subclass must implement are read(char[], int, int) and close().  Most
     * subclasses, however, will override some of the methods defined here in order
     * to provide higher efficiency, additional functionality, or both.
     *
     *
     * @see BufferedReader
     * @see   LineNumberReader
     * @see CharArrayReader
     * @see InputStreamReader
     * @see   FileReader
     * @see FilterReader
     * @see   PushbackReader
     * @see PipedReader
     * @see StringReader
     * @see Writer
     *
     * @version     %I%, %E%
     * @author    Mark Reinhold
     * @since    JDK1.1
     */
    
    public abstract class Reader implements Readable, Closeable {
    
        /**
         * 锁,在构造方法时赋值,默认使用this,也可以指定别的obj
         */
        protected Object lock;
    
        /**
         * Creates a new character-stream reader whose critical sections will
         * synchronize on the reader itself.
         */
        protected Reader() {
            this.lock = this;
        }
    
        /**
         * Creates a new character-stream reader whose critical sections will
         * synchronize on the given object.
         *
         * @param lock  The Object to synchronize on.
         */
        protected Reader(Object lock) {
            if (lock == null) {
                throw new NullPointerException();
            }
            this.lock = lock;
        }
    
        /**
         * Attempts to read characters into the specified character buffer.
         * The buffer is used as a repository of characters as-is: the only
         * changes made are the results of a put operation. No flipping or
         * rewinding of the buffer is performed.
         *
         * @param target the buffer to read characters into
         * @return The number of characters added to the buffer, or 
         *         -1 if this source of characters is at its end
         * @throws IOException if an I/O error occurs
         * @throws NullPointerException if target is null
         * @throws ReadOnlyBufferException if target is a read only buffer
         * @since 1.5
         */
        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;
        }
    
        /**
         * 读取一个字符,实现方式是先读取一个字符到一个char数组中,最后返回数组的第一个元素
         */
        public int read() throws IOException {
            char cb[] = new char[1];
            if (read(cb, 0, 1) == -1)
                return -1;
            else
                return cb[0];
        }
    
        /**
         * 读取char[]数组长度的字符到数组中
         */
        public int read(char cbuf[]) throws IOException {
            return read(cbuf, 0, cbuf.length);
        }
    
        /**
         * 交给子类实现的读取方法
         */
        abstract public int read(char cbuf[], int off, int len) throws IOException;
    
        /** Maximum skip-buffer size */
        private static final int maxSkipBufferSize = 8192;
    
        /** 用来支持skip方法的数组 */
        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;
            }
        }
    
        /**
         * 用来表示Reader中后面还有没有可读取的字符
         * 在本类中始终返回false,在子类中有自己的实现
         */
        public boolean ready() throws IOException {
            return false;
        }
    
        /**
         * Tells whether this stream supports the mark() operation. The default
         * implementation always returns false. Subclasses should override this
         * method.
         *
         * @return true if and only if this stream supports the mark operation.
         */
        public boolean markSupported() {
            return false;
        }
    
        /**
         * 在指定位置做一个标记,用处类似于ByteBuffer中的mark
         */
        public void mark(int readAheadLimit) throws IOException {
            throw new IOException("mark() not supported");
        }
    
        /**
         * 将position设置为mark
         */
        public void reset() throws IOException {
            throw new IOException("reset() not supported");
        }
    
        /**
         * Closes the stream and releases any system resources associated with
         * it.  Once the stream has been closed, further read(), ready(),
         * mark(), reset(), or skip() invocations will throw an IOException.
         * Closing a previously closed stream has no effect.
         *
         * @exception  IOException  If an I/O error occurs
         */
        abstract public void close() throws IOException;
    
    }

    MultiReader

    /*
     * Copyright (C) 2008 The Guava Authors
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package com.google.common.io;
    
    import com.google.common.base.Preconditions;
    
    import java.io.IOException;
    import java.io.Reader;
    import java.util.Iterator;
    
    /**
     * 使用多个Reader合成一个MultiReader,其中Reader被Supplier包装起来
     */
    class MultiReader extends Reader {
        private final Iterator<? extends InputSupplier<? extends Reader>> it;
        /** 当前Reader */
        private Reader current;
    
        MultiReader(Iterator<? extends InputSupplier<? extends Reader>> readers)
                throws IOException {
            this.it = readers;
            advance();
        }
    
        /**
         * 关闭当前Reader并跳到下一个reader
         */
        private void advance() throws IOException {
            close();
            if (it.hasNext()) {
                current = it.next().getInput();
            }
        }
    
        /**
         * 读取当前Reader的内容到cbuf[]中,如果当前reader已经读完,则切换到下一个reader来读取
         */
        @Override public int read(char cbuf[], int off, int len) throws IOException {
            if (current == null) {
                return -1;
            }
            int result = current.read(cbuf, off, len);
            if (result == -1) {
                advance();
                return read(cbuf, off, len);
            }
            return result;
        }
    
        /**
         * 跳过指定个数目的字符,如果当前reader已经读完,则跳到下一个reader并重新读取
         */
        @Override public long skip(long n) throws IOException {
            Preconditions.checkArgument(n >= 0, "n is negative");
            if (n > 0) {
                while (current != null) {
                    long result = current.skip(n);
                    if (result > 0) {
                        return result;
                    }
                    advance();
                }
            }
            return 0;
        }
    
        @Override public boolean ready() throws IOException {
            return (current != null) && current.ready();
        }
    
        /**
         * 关闭当前reader
         */
        @Override public void close() throws IOException {
            if (current != null) {
                try {
                    current.close();
                } finally {
                    current = null;
                }
            }
        }
    }
  • 相关阅读:
    用弦截法求解方程的根
    Fibonacci_array
    爱你所爱,行你所行
    Visual Studio安装Visual Assist的办法(兼容VS2010至VS2017)
    对集合类型属性的实体类的查询集的封装
    简单购物选择案例--纯js代码
    静态json数据表格渲染展示
    js之全选,反选,全不选案例
    常见IO流简介
    JDBC一般流程
  • 原文地址:https://www.cnblogs.com/zemliu/p/3323535.html
Copyright © 2011-2022 走看看