文件操作中的IO流——字节流与字符流

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    一IO流

    1.什么是IO流

    IO流是存取和读取数据的解决方案

    2.IO流的作用

    IO流用于读写数据这些数据包括本地文件和网络上的一些数据比如读写本地文件的时候需要用到文件读写的IO流读写网络上的数据时需要通过Socket套接字来调用数据流来进行网络数据的读写

    3.IO流的分类

    如何判断一个文件是不是纯文本文件可以将该文件用记事本的方式打开观察其是不是乱码如果是乱码说明该文件不是纯文本文件否则就是

    分别以word文件和txt文件举例分别在文件中保存一段文字“我爱中国”

    word

    word文件用记事本打开是乱码所以不是纯文本文件

    txt

    txt文件用记事本打开显示“我爱中国”所以是纯文本文件

    二字节流InputStream/OutputStream

    1.字节输出流OutputStream

    输出流指的是往内存上写入数据每次写的时候按照字节为单位进行书写

    OutputStream是一个抽象类在实例化对象时需要使用向上转型采用子类FileOutputStram这里主要是操作文件来创建对象。

    OutputStream相关方法

    修饰符及返回值类型

    方法签名

    说明

    void

    write(int b)

    写入一个整数在文件中显示对应ASCII对应的字符

    void

    write(byte[] b)

    写入一个字节数组

    int

    write(byte[] b,int off,int len)

    写入对应条件长度的字节数组

    void

    close()

    关闭字节流

    void

    flush()

    刷新缓冲区

    OutputStream中最重要的方法是writewrite方法有三种形式分别进行代码演示在进行代码示例之前我们需要知道字节流写数据时的相关细节

    字节流写数据
    1.如果文件不存在会自动创建一个文件但是要保证父亲路径存在
    2.如果文件存在会先清空文件否则需要在实例化OutputStream对象时另加一个参数设置为true(该参数的意思是支持续写)
    3.write方法的三种用法
    1) write(int b)写入一个整数但是存储的ASCII值,所以也可以直接写一个字符字符也是一个整数
    2)write(byte[] b)写入一个字节数组,所以用字节流想要写入字符串的时候需要将字符串先转换成字节数组
    3)write(byte[] b, int off, int len)将字符数组从off下标开始写len个长度的数据元素
    /**
    * 在当前项目的路径下创建一个a.txt文件
    */
    public static void main(String[] args) throws IOException {
            //创建对象
            OutputStream outputStream = new FileOutputStream("./a.txt");
            //写数据
            //1.写入一个整数文件中存储的是ASCII值
            outputStream.write(97);
            outputStream.write(98);
            //2.写入一个字节数组或者字符串如果写入的是字符串的话也需要转换成字节数组
            byte[] bytes = {97, 98, 99, 100};
            outputStream.write(bytes);
            String str1 = "abc";
            outputStream.write(str1.getBytes());
            //3.写入一个字符数组从off下标开始写len个长度的数据元素
            String str2 = "abc";
            outputStream.write(str2.getBytes(), 0, 3);
    
            //关闭资源
            outputStream.close();
        }

    第一种写法写入一个整数文件中存储的是ASCII值

    第二种写法写入一个字节数组或者字符串如果写入的是字符串的话也需要转换成字节数组

    第三种写法写入一个字符数组从off下标开始写len个长度的数据元素

    2.字节输入流InputStream

    输入流指的是从内存上读取数据每次读取的时候按照字节为单位进行读取

    InputStream是一个抽象类在实例化对象时需要使用向上转型采用子类FileInputStream这里主要是操作文件来创建对象。

    InputStream相关方法

    修饰符及返回值类型

    方法签名

    说明

    int

    read()

    读取一个字节的数据

    int

    read(byte[] b)

    最多读取b.length子节点额数据到b中返回实际读到的数量

    int

    read(byte[] b,int off,int len)

    最多读取len-off字节的数据到b中放在从off开始返回实际读到的数量

    int

    close()

    关闭字节流

    InputStream中最重要的方法是readread方法有三种形式这里主要讲解前两种在进行代码示例之前我们需要知道字节流读取数据时的相关细节

    字节流读数据
    1.如果文件不存在会直接报错和输出流写数据区分开
    2.read方法
    read()一次读取一个字节
    1)一次读一个字节返回的是该数据在ASCII表上所对应的数字如果想返回字符本身需要强转成char类型
    2)当读取的数据很多时需要循环读取的时候判断此时读到的数据是不是-1即可否则就继续读
    read(byte[] b)一次读取多个字节
    当读取的文件很大一次读取一个字节很费事的时候可以采用一次读取多个字节
    设置一个缓存数组一般数组创建的越大拷贝速度越快(但是数组创建的太大会占用内存资源)所以一般设置成1024的整数倍
    /**
    * 读取当前项目的路径下的一个a.txt文件假设存储的是abc
    */
    public static void main(String[] args) throws IOException {
            //创建对象
            InputStream inputStream = new FileInputStream("./a.txt");
    
            //读取数据
            //1.一个字节一个字节的读
            int a = inputStream.read();
            System.out.println((char) a);
            //2.循环读取
            int b = 0;//变量b一定要定义
            while ((b = inputStream.read()) != -1) {
                System.out.print((char) b);
            }
            //3.一次读取多个字节用缓存数组
            byte[] bytes = new byte[2];//一次读取多少个字节和数组的长度有关
            int len = 0;
            while ((len = inputStream.read(bytes)) != -1) {
                //每次读取之后会替换之前的字节数组
                //注意这里一定要写读取的数组的长度因为可能某一次读取的长度不足数组的长度所以只需要读len的长度即可
                System.out.println(new String(bytes, 0, len));
            }
    
            //关闭资源
            inputStream.close();
        }

    第一种读取方法一个字节一个字节的读

    第二种方法循环读取

    第三种方法一次读取多个字节用缓存数组

      • 单个字节和多个字节效率区别使用拷贝文件的案例演示

    假设有一个照片的路径为C:/Users/14611/Videos/Captures/a.png大小为6,866,962 字节
    需要拷贝到路径为D:/b.png下并命名为b.png
    观察单个字节拷贝和多个字节拷贝下的效率区别

    单子字节

    public static void main(String[] args) throws IOException {
            //创建对象需要创建两个对象
            //输入流用来读取文件
            //输出流用来将读取到的数据写入文件中
            InputStream inputStream = new FileInputStream("C:/Users/14611/Videos/Captures/a.png");
            OutputStream outputStream = new FileOutputStream("D:/b.png");
    
            //进行拷贝
            long beg = System.currentTimeMillis();
            int b = 0;
            while ((b = inputStream.read()) != -1) {
                outputStream.write(b);
            }
            long end = System.currentTimeMillis();
            //关闭资源(先创建的流最后关闭)
            outputStream.close();
            inputStream.close();
            System.out.println("拷贝花费时间为" + (end - beg) + "ms");
        }

    多个字节

    public static void main(String[] args) throws IOException {
            //创建对象需要创建两个对象
            //输入流用来读取文件
            //输出流用来将读取到的数据写入文件中
            InputStream inputStream = new FileInputStream("C:/Users/14611/Videos/Captures/a.png");
            OutputStream outputStream = new FileOutputStream("D:/c.png");
    
            //进行拷贝
            long beg = System.currentTimeMillis();
            byte[] bytes = new byte[1024 * 1024 * 5];
            int len = 0;
            while ((len = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);//写的时候要设置长度不能把整个数组都读
            }
            long end = System.currentTimeMillis();
            //关闭资源(先创建的流最后关闭)
            outputStream.close();
            inputStream.close();
            System.out.println("拷贝花费时间为" + (end - beg) + "ms");
        }

    两个方法均可以完全拷贝出相同的照片文件但是每次读取写入多个字节的方法的时间效率明显由于单个字节的方法

    三字符流Reader/Write

      • 字符输入流Reader

    字符输入流在进读取数据的时候每次都是读取一个字节遇到中文时GBK编码读两个字节读UTF-8编码读三个字节

    Reader相关方法

    修饰符及返回值类型

    方法签名

    说明

    int

    read()

    读取一个数据

    int

    read(char[] buffer)

    读取多个数据

    void

    close()

    关闭字符流

    Reader中最重要的方法是readread方法有两种形式这里主要讲解前两种在进行代码示例之前我们需要知道字符流读取数据时的相关细节

    字符流读数据底层就是字节流
    输入流一次读一个字节遇到中文时一次就会读取多个字节
    输出流底层会把数据按照指定的编码方式进行编码变成字节再写到文件中
    适用于纯文本文件进行读写操作
    1.如果文件不存在会直接报错
    2.read方法方法读取完之后会自动解码并转成十进制所以读取汉字的时候需要强转
    read():按字节进行读取遇到中文一次读多个字节读取后解码返回一个整数(GBK一次读两个字节UTF-8一次读三个字节)
    read(char[] buffer):一次读取多个并放到字符数组中
    /**
    * 读取当前项目的路径下的一个a.txt文件假设存储的是abc我爱中国
    */
    public static void main(String[] args) throws IOException {
            //创建对象
            Reader reader = new FileReader("./a.txt");
    
            //读取数据
            //1.无参的read方法
            int ch = 0;
            while ((ch = reader.read()) != -1) {
                System.out.println(ch);
            }
            //2.有参的read方法
            char[] chars = new char[2];//表示一次读两个数据
            int len = 0;
            int count = 0;
            while ((len = reader.read(chars)) != -1) {
                count++;
                //把数组的数据变成字符串再进行打印
                System.out.println(new String(chars, 0, len));
                System.out.println(count);
            }
    
            //关闭资源
            reader.close();
        }

    第一种方法无参的read方法

    第二种方法有参的read方法每次读两个数据并换行

    2.字符输出流Writer

    字符输出流在进写数据的时候每次都是写入一个字节遇到中文时GBK编码写入两个字节读UTF-8编码写入三个字节

    Writer相关方法

    Writer也有类似的几种写数据的方法但是用的最多的就是写入字符串只需了解这一种用法即可

    write方法的相关细节

    字符流写数据
    1.文件不存在会创建一个新的路径但是要保证父亲路径存在
    2.如果文件已经存在则会清空文件如果不想清空需要打开续写开关即设置成true即可
    3.如果write方法的参数是整数但是实际上写到本地文件中的是整数在字符集上对应的字符

    用的最多的方法是写一个字符串
    /**
    * 在当前项目的路径下创建一个a.txt文件
    */
    public static void main(String[] args) throws IOException {
            Writer writer = new FileWriter("./a.txt");
            writer.write("你好中国");//是12个字节
            writer.close();
        }

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6