java.io源码解析

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

2019-05-27  本文已影响0人  dark丶Night

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

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

// 用来实现同步操作,子类如果需要同步,也应使用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示例进行说明。由于输入流、输出流代码相似,并且在使用时一般都成对出现,下文也将成对讲解。

上一篇下一篇

猜你喜欢

热点阅读