美文网首页java.io源码解析
java.io源码解析(一)--字节流(InputStream、

java.io源码解析(一)--字节流(InputStream、

作者: dark丶Night | 来源:发表于2019-05-27 20:46 被阅读0次

    声明:本系列只供本人自学使用,勿喷。

    IO是每位java工程师都必须掌握的知识点,无论什么项目都会涉及文件IO、网络IO等,但是java中的IO类多达几十种,很多人在使用时会难以抉择,并且网上关于IO的学习资料比较杂乱,因此本人决定研究JDK8中rt.jar的java.io源码并总结为系列文章,如有不正之处还请多多指点。

    网上的IO教程大多是一上来就扔个降视力的大图,吓得我等小白直接X掉网页。本人痛定思痛,决定从0扩展IO体系,首先我们按照操作单元进行划分,如下图。

    程序中的所有数据都是以流的方式存储或传输,通常情况下,二进制数据(Binary)使用字节流传输、存储,文本数据(ASCII)使用字符流传输、存储、读取。

    一、字节流

    1.InputStream

    • 源码结构图
    • 核心方法

    核心方法就是read,读取InputStream并保存到byte[]

    // 返回下一个字节,如果没有则返回-1
    public abstract int read() throws IOException
    
    // 实际调用read(b, 0, b.length);
    public int read(byte b[]) throws IOException
    
    public int read(byte b[], int off, int len) throws IOException{
        1.参数检查
        2.循环read(),赋值给b
        3.返回上一步赋值给b的字节数量
    }
    
    public void close() throws IOException
    
    • 其余方法
    // 跳过n个字节
    public long skip(long n) throws IOException{
        1. size=(常量MAX_SKIP_BUFFER_SIZE与入参n的较小值)
        2. 循环read()赋值给临时数组new byte[size]
    }
    // 返回InputStream的字节数,但是并不准确
    public int available() throws IOException
    
    // 标记,回到标记位,是否支持该功能
    public synchronized void mark(int readlimit) 
    public synchronized void reset() throws IOException
    public boolean markSupported() 
    

    2.OutputStream

    • 源码结构图
    • 核心方法

    核心方法就是write,将byte[]写入OutputStream

    public abstract void write(int b) throws IOException;
    
    // 实际调用write(b, 0, b.length);
    public void write(byte b[]) throws IOException
    
    public void write(byte b[], int off, int len) throws IOException{
        1.参数检查
        2.循环write() 
    }
    
    // 保证字节数组传递给底层操作系统,不能保证操作系统已完成写入
    public void flush() throws IOException
    
    public void close() throws IOException
    

    二、字符流

    1.Reader

    • 源码结构图


    • 构造器
    // 用来实现同步操作,子类如果需要同步,也应使用synchronized (lock)
    protected Object lock;
    
    protected Reader() {
        this.lock = this;
    }
    
    protected Reader(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }
    
    • 核心方法

    核心方法就是read,读取Reader并保存到char[]

    // 返回下一个字符,如果没有则返回-1
    public int read() throws IOException 
    
    // 实际调用read(cbuf, 0, cbuf.length);
    public int read(char cbuf[]) throws IOException
    
    abstract public int read(char cbuf[], int off, int len) throws IOException
    
    //JDK5新增
    public int read(java.nio.CharBuffer target) throws IOException{
        1.读取target.remaining()个字符到char[]
        2.将char[]赋值给target
    }
    
    public void close() throws IOException
    
    • 其余方法
    // 跳过n个字节
    public long skip(long n) throws IOException{
        1. size=(常量maxSkipBufferSize与入参n的较小值)
        2. 循环read()赋值给临时数组new byte[size]
    }
    // 下一次read()是否阻塞
    public boolean ready() throws IOException
    
    // 标记,回到标记位,是否支持该功能
    public synchronized void mark(int readlimit) 
    public synchronized void reset() throws IOException
    public boolean markSupported() 
    

    2.Writer

    • 源码结构图


    • 构造器(同Reader)
    // 用来实现同步操作,子类如果需要同步,也应使用synchronized (lock)
    protected Object lock;
    
    protected Writer() {
        this.lock = this;
    }
    
    protected Writer(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }
    
    • 核心方法

    核心方法
    ① write,将char[] 写入Writer
    ② append,将CharSequence追加到Writer

    // 以下方法实际调用write(char cbuf[], int off, int len)
    public void write(int c) throws IOException
    public void write(char cbuf[]) throws IOException
    public void write(String str) throws IOException
    public void write(String str, int off, int len) throws IOException
    //JDK5新增
    public Writer append(CharSequence csq) throws IOException
    public Writer append(CharSequence csq, int start, int end) throws IOException
    public Writer append(char c) throws IOException
    
    abstract public void write(char cbuf[], int off, int len) throws IOException;
    
    // 保证字符数组传递给底层操作系统,不能保证操作系统已完成写入
    public void flush() throws IOException
    
    public void close() throws IOException
    

    三、总结

    • 字节流通过字节数组byte[]进行读写操作,InputStream核心方法是read(byte b[], int off, int len),OutputStream核心方法是write(byte b[], int off, int len)
    • 字符流通过字符数组char[]进行读写操作,Reader核心方法是read(char cbuf[], int off, int len),Writer核心方法是write(char cbuf[], int off, int len)
    • 无论读取哪种流,read返回值为-1表示结束,其他值则表示已读取到数组中的数量。

    本节讨论的类都是抽象类,力求从宏观上了解这些类各自的作用,接下来的系列将深入具体的实现类源码,并用简单demo示例进行说明。由于输入流、输出流代码相似,并且在使用时一般都成对出现,下文也将成对讲解。

    相关文章

      网友评论

        本文标题:java.io源码解析(一)--字节流(InputStream、

        本文链接:https://www.haomeiwen.com/subject/djshtctx.html