【Java基础】IO流

我是 啤酒就辣条,一个Java。
学而时习之,不亦说乎?但愿经过博客的形式,总结、分享,梳理本身、帮助他人。
另外,啤酒就辣条,味道不错哦~

流的定义

流是一组有序的字节集合,是对数据传输的抽象。流的本质是数据传输,根据传输的特性,流又被分为多种状况。java

流的分类

按照数据类型能够分为字符流字节流缓存

字节流基本单位是一个字节(8bit),能够处理全部类型的数据。app

字符流基本代为是多个字节(通常是两个字节),通常处理字符数据。字符流某种意义能够看做,被包装过的字节流。由于字符流是基于字节流读取以后,查了特定的码表,进行字符转换的。因此,若是是字符类型的数据传输,首先使用字符流,其余传输使用字节流。this

按照输入输出方向可分为输入流输出流输入流只能进行读操做。输出流只能进行写操做。指针

Java种的类

根据流的分类,可得字节输入流,字节输出流,字符输入流,字符输出流。这四种分类分别对四个抽象类InputStream、OutputStream、Reader、Writer,Java种全部的IO流类都是继承其一。code

字节输入流

InputStream是全部字节输入流的超类。既然是输入流,确定会有读的方法read()对象

/**
* @param    b 当前缓存区的数据
* @param    off 当前缓存区已写入的位置
* @param    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();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
         // 这里能够看出是一个bit位一个bit位读进缓存区的
        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; 
    }

这个方法逻辑很清晰了,首先判断缓存区能不能放下输入的数据,而后以字节为单位读进缓存区。继承

还有个方法是跳过或者丢弃输入流的前n个字节,可是结果跳过的字节数可能小于n。ip

/**
* @param n 要跳过的字节数
*/
public long skip(long n) throws IOException {
        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;
        }
        // 请注意此时 remaining 可能不为0。
        return n - remaining;
    }

还有几个方法:资源

available()返回可读字节数的估计值。

close()关闭字节输入流,并释放相应资源。

mark(int readlimit)在输入流种标记当前位置。

reset()将此流从新定位到mark()的位置。

markSupported()查询此输入流是否支持mark()和reset()方法。

这里主要说明一下mark()和reset()方法。正常状况下,一个流只能读一次。 mark()能够做为标记,某一时刻使用reset()方法让指针从新回到标记处。

字节输出流

OutputStream是全部字节输入流的超类。既然是输入流,确定会有读的方法write()

主要方法有三个。

write()将指定的字节转化成输出流。

flush()将缓存区数据强制刷新出去,刷新到文件或者外设中。

close()关闭字节输出流,并释放相应资源。

对于InputStreamOutputStream提供的方法不少没有带锁,但每每实现的时候都会带上锁。例如每每会加上synchronized

字符输入流

Reader是全部字符输入流的超类。

大部分方法和InputStream差很少,只是从字节变成了字符。只是Reader提供了对象级别的锁。

protected Object lock;

protected Reader() {
    this.lock = this;
}

字符输出流

Writer是全部字符输入流的超类。固然,Writer也提供了对象级别的锁。

protected Object lock;

protected Writer() {
    this.lock = this;
}

除此以外,WriterOutputStream多了append()方法。

append()方法是数据的追加。

write()方法是数据的覆盖。

相关文章
相关标签/搜索