Io汇总(四) Reader 以及子类

Readable

interface Readable  

A Readable是一个字符源

int read(CharBuffer cb)    尝试将字符读入指定的字符缓冲区。  

Reader

public abstract class Reader implements Readable, Closeable

用于读取字符流的抽象类

abstract void close()  关闭流并释放与之相关联的任何系统资源。  
void mark(int readAheadLimit) 标记流中的当前位置。  
boolean markSupported() 告诉这个流是否支持mark()操作。  
int read() 读一个字符  
int read(char[] cbuf) 将字符读入数组。  
abstract int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。  
int read(CharBuffer target) 尝试将字符读入指定的字符缓冲区。  
boolean ready() 告诉这个流是否准备好被读取。  
void reset() 重置流。  
long skip(long n) 跳过字符        

具体读取操作在子类实现

 abstract public int read(char cbuf[], int off, int len) throws IOException;

skip(long n)  读取的时候跳过n个字符     

 private static final int maxSkipBufferSize = 8192;// 最大可以跳过的字符集
 
 public long skip(long n) throws IOException {
        
        int nn = (int) Math.min(n, maxSkipBufferSize);
        synchronized (lock) {
            if ((skipBuffer == null) || (skipBuffer.length < nn))
                skipBuffer = new char[nn]; //new 一个要跳过多少字符的容器
            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;
        }
    }

InputStreamReader   

public class InputStreamReader extends Reader 

InputStreamReader是从字节流到字符流的桥

String getEncoding()  返回此流使用的字符编码的名称。 

 int read()

 private final StreamDecoder sd;  //真正处理类
 
public int read() throws IOException {
        return sd.read();
    }

FileReader

public class FileReader extends InputStreamReader

public FileReader(File file) 

 public FileReader(File file) throws FileNotFoundException {
        super(new FileInputStream(file));
    }

没有实现类 全都使用的是父类  InputStreamReader 的方法

BufferedReader

public class BufferedReader extends Reader

从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。 

Stream<String> lines()  返回一个 Stream ,其元素是从这个 BufferedReader读取的行。  
String readLine()  读一行文字。 

private char cb[]; //缓存字符的数组
private int nChars, nextChar;//缓存字符的个数  下一个字符的下标
private static final int INVALIDATED = -2;//标记失效常量 
private static final int UNMARKED = -1;// 没有标记
private int markedChar = UNMARKED;// 标记位置的下标
private int readAheadLimit = 0; //标记长度上限

 int read()

public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            for (;;) {
                if (nextChar >= nChars) {
                    fill();
                    if (nextChar >= nChars)
                        return -1;
                }
                if (skipLF) {
                    skipLF = false;
                    if (cb[nextChar] == '\n') {
                        nextChar++;
                        continue;
                    }
                }
                return cb[nextChar++];
            }
        }
    }

void fill()

private void fill() throws IOException {
        int dst; 
        if (markedChar <= UNMARKED) { // 没有标记
            dst = 0;
        } else {                                    //以下情况都有标记
            int delta = nextChar - markedChar; 
            if (delta >= readAheadLimit) { // 超过标记上限   
                markedChar = INVALIDATED;  //设置标记失效
                readAheadLimit = 0; 
                dst = 0;
            } else {                                // 没有超过标记上限
                if (readAheadLimit <= cb.length) { //标记上限比数组长度小
                    // 数据拷贝 从标记位置开始 缓存 
                    System.arraycopy(cb, markedChar, cb, 0, delta); //
                    markedChar = 0;
                    dst = delta;
                } else { // 标记上限比数组长度大
                    int nlength = cb.length * 2;
                    if (nlength > readAheadLimit) {
                        nlength = readAheadLimit;
                    }                
                    char ncb[] = new char[nlength]; //扩容缓存数组 
                    System.arraycopy(cb, markedChar, ncb, 0, delta);
                    cb = ncb;
                    markedChar = 0;
                    dst = delta;
                }
                nextChar = nChars = delta;
            }
        }
        int n;
        do {
            n = in.read(cb, dst, cb.length - dst); // 读取数据 由装饰对象实现
        } while (n == 0); 
        if (n > 0) {
            nChars = dst + n;
            nextChar = dst;
        }
    }

String readLine(boolean ignoreLF)

String readLine(boolean ignoreLF) throws IOException {
        StringBuffer s = null;
        int startChar;

        synchronized (lock) {
            ensureOpen();
            boolean omitLF = ignoreLF || skipLF;

        bufferLoop:        //跳出for循环的标签
            for (;;) {

                if (nextChar >= nChars) //
                    fill();
                if (nextChar >= nChars) { 
                    if (s != null && s.length() > 0)
                        return s.toString();
                    else
                        return null;
                }
                boolean eol = false;
                char c = 0;
                int i;

                /* Skip a leftover '\n', if necessary */
                if (omitLF && (cb[nextChar] == '\n'))
                    nextChar++;
                skipLF = false;
                omitLF = false;

            charLoop:
                for (i = nextChar; i < nChars; i++) {
                    c = cb[i];
                    if ((c == '\n') || (c == '\r')) { //查找 换行符
                        eol = true;
                        break charLoop;
                    }
                }

                startChar = nextChar;
                nextChar = i;

                if (eol) {
                    String str;
                    if (s == null) {
                        str = new String(cb, startChar, i - startChar);
                    } else {
                        s.append(cb, startChar, i - startChar);
                        str = s.toString();
                    }
                    nextChar++;
                    if (c == '\r') {
                        skipLF = true;
                    }
                    return str;
                }

                if (s == null)
                    s = new StringBuffer(defaultExpectedLineLength);
                s.append(cb, startChar, i - startChar);
            }
        }
    }

 void mark(int readAheadLimit)   标记字符当前位置

  // readAheadLimit 标记字符上限(最多标记字符的长度)
 public void mark(int readAheadLimit) throws IOException { 
        synchronized (lock) {
            ensureOpen();
            this.readAheadLimit = readAheadLimit;
            markedChar = nextChar;
            markedSkipLF = skipLF;
        }
    }

void reset()  恢复到标记字符位置

 public void reset() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (markedChar < 0)
                throw new IOException((markedChar == INVALIDATED)
                                      ? "Mark invalid"
                                      : "Stream not marked");
            nextChar = markedChar; //
            skipLF = markedSkipLF; // 
        }
    }

CharArrayReader 

public class CharArrayReader extends Reader

protected char[] buf 字符缓冲区。  
protected int count 这个缓冲区结束的索引。  
protected int markedPos 标记在缓冲区中的位置。  
protected int pos 当前的缓冲位置。  

int read()

 public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (pos >= count) //读完了
                return -1;
            else
                return buf[pos++]; //返回字符
        }
    }

int read(char b[], int off, int len) 

public int read(char b[], int off, int len) throws IOException {
        synchronized (lock) {
            ....
            if (pos + len > count) {
                len = count - pos;
            }
            if (len <= 0) {
                return 0;
            }
            System.arraycopy(buf, pos, b, off, len);
            pos += len;
            return len;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值