IO流3.InputStream和OutputStream

一.应用程序操作IO的流程

  1. 当进程需要进行IO读写的时候,通过一个特殊的指令,进程进入内核空间, 读取IO到内核空间
  2. 进程再将IO拷贝到用户空间

二.InputStream

  • 所有字节输入流的父类
  • read()操作会一直等待IO堵塞,除非到达流末尾或者抛出异常

常用的字节输入流及其继承关系

/**
 * 抽象输入流
 * 所有字节输入流的父类
 * 定义了输入流的通用方法
 */
public abstract class InputStream implements Closeable {

    //最大可跳过的字节数
    //私有常量
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;
    
    /**
     * 抽象方法,每个子类都需要实现该方法,
     * 从输入流中读取一个字节,
     * 所以返回值的范围是[0,255],
     * 除了ASCII码,其余打印字符都会乱码,
     * 该方法效率较为低下
     * @return 返回的是无符号字节数值,
     *         当读取到文件结尾,那么返回-1
     */
    public abstract int read() throws IOException;

    /**
     * 从流中读取数组b长度的字节,
     * 然后放到字节数组中
     * 注意: 
     *      当返回值小于b.length的时候,
     *      说明b数组没有被填满,
     *      其中[0,返回值]才是真正读取的数据,
     *      而[返回值,b.length]是数组中原有的数据
     *
     * @param b 保存读取数据的字节数组
     * @return 实际读取数据的长度
     *         如果返回-1,说明到了流的末尾
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    /**
     * 从流中读取len长度的字节数据,
     * 然后将数据放到数组b中,放入的位置从off开始,
     * 注意:
     *      当返回值小于len的时候,
     *      说明b数组没有被填满,
     *      其中[off,返回值]才是真正读取的数据,
     *      而[返回值,len]是数组中原有的数据
     *
     * @param b 保存读取流中数据的字节数组
     * @param off 字节数组的写入数据索引的偏移
     * @param len 写入字节数组数据的长度
     * @return 实际读取数据的长度
     *         如果返回-1,说明到了流的末尾
     */
    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) {
            //如果到了流的末尾,那么返回-1
            return -1;
        }
        //将读取到的数据,缓存到b数组中
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                //循环读取数据,一直读到len长度
                c = read();
                if (c == -1) {
                    //到了流的尾部,那么结束循环
                    break;
                }
                //将数据保存到b数组中
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        //返回读取的长度
        return i;
    }

    /**
     * 跳过并丢弃n个字节,
     * 之后的读取操作从n字节之后继续进行
     * @return 返回的是实际跳过的字节数
     */
    public long skip(long n) throws IOException {

        long remaining = n;
        int nr;

        if (n <= 0) {
            return 0;
        }
        
        //跳过的最大长度为MAX_SKIP_BUFFER_SIZE
        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) {
            //跳过操作是通过read()方法来实现的
            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 {}

    /**
     * 标记流
     * 作用是记录当前流读取到的位置,
     * 当后续调用reset()方法时, 可以回到mark标记的位置 
     *
     * 默认不支持标记
     * 所以没有做任何操作
     */
    public synchronized void mark(int readlimit) {}

    /**
     * 重置标记
     * 将流重新定位到上一次调用mark方法时的位置 
     * 
     * 默认不支持标记重置
     */
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    /**
     * 测试输入流是否支持mark和reset方法 
     * 默认不支持标记
     */
    public boolean markSupported() {
        return false;
    }

}

三.OutputStream

  • 所有字节输出流的父类
  • write()操作会一直等待IO堵塞,除非到达流末尾或者抛出异常

常用的字节输入流及其继承关系

/**
 * 抽象输出流
 * 所有字节输出流的父类
 * 定义了通用的字节输出流的通用方法
 */
public abstract class OutputStream implements Closeable, Flushable {

    /**
     * 将一个字节,写入到输出流中
     * 抽象方法,所有的子类都必须实现该方法
     * 该方法效率较低
     */
    public abstract void write(int b) throws IOException;

    /**
     * 将b中的数据,全部写入到输出流中
     */
    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    /**
     * 从字节数组b的off位置开始,取出len长度的数据
     * 写入到输出流中
     * @param b 取出数据的字节数组
     * @param off 从b中取出数据的起始位置
     * @param len 从b中取出数据的长度
     */
    public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            //通过write()方法实现
            write(b[off + i]);
        }
    }

    /**
     * 刷新数据
     * 如果流中使用了byte数组缓存
     * 调用该方法会将缓存的byte数组更新到流里面
     */
    public void flush() throws IOException {
    }

    /**
     * 关闭流
     */
    public void close() throws IOException {
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,541评论 0 5
  • 1、IO流 1.1、概述 之前学习的File类它只能操作文件或文件夹,并不能去操作文件中的数据。真正保存数据的是文...
    Villain丶Cc阅读 2,670评论 0 5
  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 5,967评论 3 28
  • 计算机系统漫游 代码从文本到可执行文件的过程(c语言示例):预处理阶段,处理 #inlcude , #defin...
    willdimagine阅读 3,584评论 0 5
  • 文 夏昀 夜晚,月亮没来, 第二天也没来 第三天,第四天……… 终于月亮回来了,...
    夏昀2008阅读 181评论 0 0