java--IO流(详)

IO流也称为输入、输出流,就是用来读写数据的。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16

一.概述:

1.IO流的作用?

读写文件数据的

2.IO流是怎么划分的,大体分为几类,各自的作用?

  • 字节流:字节输入流,字节输出流(读写字节数数据的)
  • 字符流:字符输入流,字符输出流(读写字符数据的)

3.意义

  • I表示intput,是数据从硬盘文件读入到内存的过程,称之输入,负责读。
  • O表示output,是内存程序的数据从内存到写出到硬盘文件的过程,称之输出,负责写。

二.分类

1.按流的方向分:

输入流,输出流;

2.按流中的最小单位分:

字节流:操控所以类型的文件;

字符流:只能操控重文本文件;

3.总结流的四大类:
         字节流                                               
        字节输入流            字节输出流              
        InputStream          OutputStream          
        FileInputStream      FileOutputStream    

 字符流 

字符输入流        字符输出流

Reader           Writer  (抽象类)

FileReader       FileWriter(实现类,可以使用的)

    文件字节输入流:FileInputStream(负责读取数据)

        -- 作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。

                按照字节读文件数据到内存中。

        -- 构造器:

            public FileInputStream(File file):创建字节输入流管道与源文件对象接通

            public FileInputStream(String pathname):创建字节输入流管道与源文件路径接通。

        -- 方法:

            public int read(): 每次读取一个字节返回,读取完毕返回-1。

    小结:
        一个一个字节读取中文数据输出其实是被淘汰的,性能极差!
         一个一个字节读取中文数据输出,会出现截断中文字节的情况,无法避免读取中文输出乱码的问题。

  public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输入流管道与源文件接通。
        // InputStream is = new FileInputStream(new File("file-io-app\\src\\data.txt"));
        // 简化写法
        InputStream is = new FileInputStream("file-io-app\\src\\data.txt");

        // 2、读取一个字节返回 (每次读取一滴水)
//        int b1 = is.read();
//        System.out.println((char)b1);
//
//        int b2 = is.read();
//        System.out.println((char)b2);
//
//        int b3 = is.read();
//        System.out.println((char)b3);
//
//        int b4 = is.read(); // 读取完毕返回-1
//        System.out.println(b4);

        // 3、使用循环改进
        // 定义一个变量记录每次读取的字节    a  b  3   爱
        //                              o o  o   [ooo]
        int b;
        while (( b = is.read() ) != -1){
            System.out.print((char) b);
        }
    }

文件字节输出流:  FileOutputStream(可以直接创建文件,并存数据)

 -- 作用:以内存为基准,把内存中的数据,按照字节的形式写出到磁盘文件中去。
                 简单来说,把内存数据按照字节写出到磁盘文件中去。
        -- 构造器:
            public FileOutputStream(File file):创建一个字节输出流管道通向目标文件对象。
            public FileOutputStream(String file):创建一个字节输出流管道通向目标文件路径。
            public FileOutputStream(File file , boolean append):创建一个追加数据的字节输出流管道通向目标文件对象。
            public FileOutputStream(String file , boolean append):创建一个追加数据的字节输出流管道通向目标文件路径。
        -- 方法:
           public void write(int a):写一个字节出去 。
           public void write(byte[] buffer):写一个字节数组出去。
           public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。
                           参数一,字节数组;参数二:起始字节索引位置,参数三:写多少个字节数出去。
    小结:
        换行:  os.write("\r\n".getBytes()); // 换行
        追加数据管道: OutputStream os = new FileOutputStream("day10_demo/out01.txt" , true); // 追加管道!!

public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("file-io-app/src/out04.txt" , true); // 追加数据管道
//        OutputStream os = new FileOutputStream("file-io-app/src/out04.txt"); // 先清空之前的数据,写新数据进入

        // 2、写数据出去
        // a.public void write(int a):写一个字节出去
        os.write('a');
        os.write(98);
        os.write("\r\n".getBytes()); // 换行
        // os.write('徐'); // [ooo]

        // b.public void write(byte[] buffer):写一个字节数组出去。
        byte[] buffer = {'a' , 97, 98, 99};
        os.write(buffer);
        os.write("\r\n".getBytes()); // 换行

        byte[] buffer2 = "我是中国人".getBytes();
//        byte[] buffer2 = "我是中国人".getBytes("GBK");
        os.write(buffer2);
        os.write("\r\n".getBytes()); // 换行


        // c. public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。
        byte[] buffer3 = {'a',97, 98, 99};
        os.write(buffer3, 0 , 3);
        os.write("\r\n".getBytes()); // 换行

        // os.flush(); // 写数据必须,刷新数据 可以继续使用流
        os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用了
    }

文件字符输入流:FileReader
         -- 作用:以内存为基准,把磁盘文件的数据以字符的形式读入到内存。
            简单来说,读取文本文件内容到内存中去。

         -- 构造器:
            public FileReader(File file):创建一个字符输入流与源文件对象接通。
            public FileReader(String filePath):创建一个字符输入流与源文件路径接通。

         -- 方法:
            public int read(): 读取一个字符的编号返回! 读取完毕返回-1
            public int read(char[] buffer):读取一个字符数组,读取多少个字符就返回多少个数量,读取完毕返回-1
     小结:
        字符流一个一个字符的读取文本内容输出,可以解决中文读取输出乱码的问题。
        字符流很适合操作文本文件内容。
        但是:一个一个字符的读取文本内容性能较差!!

  public static void main(String[] args) throws Exception {
        // 目标:每次读取一个字符。
        // 1、创建一个字符输入流管道与源文件接通
        Reader fr = new FileReader("file-io-app\\src\\data06.txt");

        // 2、读取一个字符返回,没有可读的字符了返回-1
//        int code = fr.read();
//        System.out.print((char)code);
//
//        int code1 = fr.read();
//        System.out.print((char)code1);

        // 3、使用循环读取字符
        int code;
        while ((code = fr.read()) != -1){
            System.out.print((char) code);
        }
    }

文件字符输出流的使用:FileWriter
        -- 作用:以内存为基准,把内存中的数据按照字符的形式写出到磁盘文件中去。
            简单来说,就是把内存的数据以字符写出到文件中去。
        -- 构造器:
           public FileWriter(File file):创建一个字符输出流管道通向目标文件对象。
           public FileWriter(String filePath):创建一个字符输出流管道通向目标文件路径。
           public FileWriter(File file,boolean append):创建一个追加数据的字符输出流管道通向目标文件对象。
           public FileWriter(String filePath,boolean append):创建一个追加数据的字符输出流管道通向目标文件路径。
        -- 方法:
             a.public void write(int c):写一个字符出去
             b.public void write(String c)写一个字符串出去:
             c.public void write(char[] buffer):写一个字符数组出去
             d.public void write(String c ,int pos ,int len):写字符串的一部分出去
             e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
     小结:
        字符输出流可以写字符数据出去,总共有5个方法写字符。
        覆盖管道:
              Writer fw = new FileWriter("Day10Demo/src/dlei03.txt"); // 覆盖数据管道
        追加数据管道:
              Writer fw = new FileWriter("Day10Demo/src/dlei03.txt",true); // 追加数据管道
        换行:
             fw.write("\r\n"); // 换行
        结论:读写字符文件数据建议使用字符流。复制文件建议使用字节流。

 public static void main(String[] args) throws Exception {
        // 1、创建一个字符输出流管道与目标文件接通
        // Writer fw = new FileWriter("file-io-app/src/out08.txt"); // 覆盖管道,每次启动都会清空文件之前的数据
        Writer fw = new FileWriter("file-io-app/src/out08.txt", true); // 覆盖管道,每次启动都会清空文件之前的数据

//      a.public void write(int c):写一个字符出去
        fw.write(98);
        fw.write('a');
        fw.write('徐'); // 不会出问题了
        fw.write("\r\n"); // 换行

//       b.public void write(String c)写一个字符串出去
        fw.write("abc我是中国人");
        fw.write("\r\n"); // 换行


//       c.public void write(char[] buffer):写一个字符数组出去
        char[] chars = "abc我是中国人".toCharArray();
        fw.write(chars);
        fw.write("\r\n"); // 换行


//       d.public void write(String c ,int pos ,int len):写字符串的一部分出去
        fw.write("abc我是中国人", 0, 5);
        fw.write("\r\n"); // 换行


//       e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        fw.write(chars, 3, 5);
        fw.write("\r\n"); // 换行


        // fw.flush();// 刷新后流可以继续使用
        fw.close(); // 关闭包含刷线,关闭后流不能使用

    }

三.编码和解码

我们正常写一个字节流输出“abc”还好,但是我们输出我们中国的文化瑰宝,汉字的时候为何会变成不知名的字符:

        String s="中国";
        byte[] by=s.getBytes(StandardCharsets.UTF_8);
        byte[] by1=s.getBytes("GBK");
        System.out.println(Arrays.toString(by));
        System.out.println(Arrays.toString(by1));

5f90790307d142539d80357d4d233abd.png

 这个时候我们就需要到了编码和解码

GBXXX字符集:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16

Unicode字符集: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 我们通常使用的是GBK和UTF-8;

第一种:直接型

        编码

        ●byte[] getBytes0:使用平台的默认字符集将该String编码为-系列字节, 将结果存储到新的字节数组中

        ●byte[] getBytes(String charsetName):使用指定的字符集将该String编码为-系列字节,将结果存储到新的字节数组中

        解码

        ●String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String

         ●String(bytel[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的String

 第二种:字符流

         字符输入转换流InputStreamReader

          -- 作用:可以解决字符流读取不同编码乱码的问题。
                  也可以把原始的字节流按照指定编码转换成字符输入流

          -- 构造器:
                public InputStreamReader(InputStream is):可以使用当前代码默认编码转换成字符流,几乎不用!
                public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)

          小结:
        字符输入转换流InputStreamReader:作用:可以解决字符流读取不同编码乱码的问题。
        public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)

          字符输出转换流:OutputStreamWriter

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16
           -- 作用:可以指定编码把字节输出流转换成字符输出流。
                   可以指定写出去的字符的编码。
           -- 构造器:
                public OutputStreamWriter(OutputStream os) :   用当前默认编码UTF-8把字节输出流转换成字符输出流
                public OutputStreamWriter(OutputStream os , String charset):指定编码把字节输出流转换成字符输出流
           小结:
          字符输出转换流OutputStreamWriter可以指定编码把字节输出流转换成字符输出流。
          从而实现指定写出去的字符编码!

四.缓冲流

1.概述

         缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。

        作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 2.缓冲流的作用:

         缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能

 3.缓冲流种类:

        字节缓冲流 字节缓冲输入流: BufferedInputStream  

        字节缓冲输出流:BufferedOutputStream

        字符缓冲流 字符缓冲输入流:BufferedReader

        字符缓冲输出流:BufferedWriter

4.字节缓冲流:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rW357u1aG9uZw==,size_20,color_FFFFFF,t_70,g_se,x_16

(1).字节缓冲流性能优化原理:

        字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。

        字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。

(2).缓冲输入,输出流

         字节缓冲输入流:BufferedInputStream,提高字节输入流读取数据的性能,读写功能上并无变化。  

        字节缓冲输出流:BufferedOutputStream,提高字节输出流读取数据的性能,读写功能上并无变化。

构造器

说明

public BufferedInputStream

​(InputStream is)

可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,

从而提高字节输入流读数据的性能

public BufferedOutputStream​(OutputStream os)

可以把低级的字节输出流包装成一个高级的缓冲字节输出流,

从而提高写数据的性能

5.字符缓冲输入流

(1)字符缓冲输入流:BufferedReader。

         作用:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。 

构造器

说明

public BufferedReader​(Reader r)

可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,

从而提高字符输入流读数据的性能

字符缓冲输入流新增功能: 

方法

说明

public String readLine()

读取一行数据返回,如果读取没有完毕,无行可读返回null

(2)字符缓冲流算解答:

字符缓冲流为什么提高了操作数据的性能?

        字符缓冲流自带8K缓冲区 可以提高原始字符流读写数据的性能

字符缓冲流的功能如何使用?

         public BufferedReader​(Reader r) 性能提升了,多了readLine()按照行读取的功能(一次读取一行数据)

         public BufferedWriter​(Writer w) 性能提升了,多了newLine()换行的功能 

        

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海绵hong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值