Java之IO概述

  java.io包里的类太多了,第一次看到这些API时会感觉非常零乱,实际上是因为里面用了装饰者模式(设计模式中写),会一层层包装扩展,因此类会很多,显得很琐碎。里面的绝大部分类图如下,图片来自:http://davidisok.iteye.com/blog/2106489

                           

     java中读取文件内容或者写入文件内容都是以流的形式来操作,流可以想象成一个"管道",“管道”的两端分别连接着文件和程序,如下:

                                            

     java中io流按照数据流的方向不同可分为输入流、输出流。按照处理数据单位的不同可分为字节流和字符流(字节流一次处理一个字节,字符流一次处理两个字节)。并且所有的流分别继承以下四种抽象流类型:


     如果io流按照功能的不同还可以分为节点流和处理流。节点流是可以直接从一个特定的数据源(节点)读写数据。



  处理流是连接在已存在的流(节点流和处理流)之上,通过对数据的处理为程序提供更为强大的功能。说白了,处理流就是在原来的节点流或者处理流上进行一层包装、扩展(装饰者),提供更为强大的功能。


InputStream、OutputStream、Reader、Writer源码如下:

public abstract class InputStream implements Closeable {//字节输入流的所有类的超类       JDK1.7   java.util
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;//最多能跳过的字节数
    public abstract int read() throws IOException;//从输入流中读取数据的下一个字节。即一根管道连着文件,从文件中读取一个字节给程序
    public int read(byte b[]) throws IOException {//从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中
        return read(b, 0, b.length);
    }
    //将输入流中最多 len个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值
    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();//存储的数组不能为空
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();//off表示数组中写入数据的初始偏移量,参数进行校验
        } else if (len == 0) {
            return 0;//此时不读入数据
        }
        int c = read();//读取一个字节
        if (c == -1) {//-1代表到了文件末尾
            return -1;
        }
        b[off] = (byte)c;
        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;//循环写入字节
            }
        } catch (IOException ee) {
        }
        return i;
    }
    public long skip(long n) throws IOException {//跳过和丢弃此输入流中数据的 n个字节
        long remaining = n;
        int nr;
        if (n <= 0) {
            return 0;
        }
        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);//获取较小值
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) {
            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }
        return n - remaining;
    }
    public int available() throws IOException {
        return 0;
    }
    public void close() throws IOException {}//关闭此输入流并释放与该流关联的所有系统资源。即直接关闭管道
    public synchronized void mark(int readlimit) {}//在此输入流中标记当前的位置
    public synchronized void reset() throws IOException {//将此流重新定位到最后一次对此输入流调用 mark方法时的位置
        throw new IOException("mark/reset not supported");
    }
    public boolean markSupported() {//测试此输入流是否支持 mark 和 reset方法
        return false;
    }
}


public abstract class OutputStream implements Closeable, Flushable {//字节输出流的所有类的超类
    public abstract void write(int b) throws IOException;//将指定的字节写入此输出流。写入参数 b的八个低位。b的 24个高位将被忽略
    public void write(byte b[]) throws IOException {//将 b.length个字节从指定的 byte数组写入此输出流
        write(b, 0, b.length);
    }
    //将指定 byte 数组中从偏移量 off开始的 len个字节写入此输出流
    public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();//字节不能为null
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {//参数校验
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {//写入长度为0直接返回
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);//写入字节
        }
    }
    public void flush() throws IOException {//刷新此输出流并强制写出所有缓冲的输出字节
    }
    //关闭此输出流并释放与此流有关的所有系统资源。即直接关闭管道。应先调用flush刷新缓冲区再关闭
    public void close() throws IOException {
    }
}


public abstract class Reader implements Readable, Closeable {//用于读取字符流的抽象类
    protected Object lock;//用于同步针对此流的操作的对象
    protected Reader() {
        this.lock = this;//创建一个新的字符流 reader
    }
    protected Reader(Object lock) {//创建一个新的字符流 reader
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }
    public int read(java.nio.CharBuffer target) throws IOException {//试图将字符读入指定的字符缓冲区。cbuf - 目标缓冲区 
        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);
    }
    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;
    }
    public boolean markSupported() {//判断此流是否支持 mark()操作
        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;//关闭该流并释放与之关联的所有资源。即直接关闭管道
}


public abstract class Writer implements Appendable, Closeable, Flushable {//写入字符流的抽象类
    private char[] writeBuffer;//
    private final int writeBufferSize = 1024;
    protected Object lock;//用于同步针对此流的操作的对象。
    protected Writer() {//创建一个新的字符流 writer
        this.lock = this;
    }
    protected Writer(Object lock) {//创建一个新的字符流 writer
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }
    public void write(int c) throws IOException {//写入单个字符。要写入的字符包含在给定整数值的 16个低位中,16高位被忽略
        synchronized (lock) {
            if (writeBuffer == null){
                writeBuffer = new char[writeBufferSize];
            }
            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 <= writeBufferSize) {
                if (writeBuffer == null) {
                    writeBuffer = new char[writeBufferSize];
                }
                cbuf = writeBuffer;
            } else {    // Don't permanently allocate very large buffers.
                cbuf = new char[len];
            }
            str.getChars(off, (off + len), cbuf, 0);
            write(cbuf, 0, len);
        }
    }
    public Writer append(CharSequence csq) throws IOException {//将指定字符序列添加到此 writer
        if (csq == null)
            write("null");
        else
            write(csq.toString());
        return this;
    }
  //将指定字符序列的子序列添加到此 writer.Appendable。
    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;
    }
    //将指定字符添加到此 writer
    public Writer append(char c) throws IOException {
        write(c);
        return this;
    }
    abstract public void flush() throws IOException;//刷新该流的缓冲
    abstract public void close() throws IOException;//关闭此流,但记得要先刷新它

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值