zoukankan      html  css  js  c++  java
  • 【Java基础】IO流

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

    流的定义

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

    流的分类

    按照数据类型可以分为字符流字节流

    字节流基本单位是一个字节(8bit),可以处理所有类型的数据。

    字符流基本代为是多个字节(一般是两个字节),一般处理字符数据。字符流某种意义可以看作,被包装过的字节流。因为字符流是基于字节流读取之后,查了特定的码表,进行字符转换的。所以,如果是字符类型的数据传输,首先使用字符流,其他传输使用字节流。

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

    Java种的类

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

    字节输入流

    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。

    /**
    * @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()方法是数据的覆盖。

  • 相关阅读:
    激活函数
    第五章 Odoo 12开发之导入、导出以及模块数据
    第四章 Odoo 12 开发之模块继承
    第三章 Odoo 12 开发之创建第一个 Odoo 应用
    第二章 Odoo 12开发之开发环境准备
    第一章 使用开发者模式快速入门 Odoo 12
    【linux之路】常用的命令
    【python之路46】内置函数2,是【python之路18】的补充
    【python之路45】tornado的用法 (三)
    【python之路44】tornado的用法 (二)
  • 原文地址:https://www.cnblogs.com/pjjlt/p/12408026.html
Copyright © 2011-2022 走看看