万字长文带你了解掌握IO流


1、简介

IO流,什么是IO?

I:Input
O:Output

通过IO可以完成对硬盘文件的读和写。


2、IO流的分类

一:按照流的方向进行分类:
       以内存作为参照物。往内存中去,叫做输入(Input)。或者叫做读(Read),从内存中出来,叫做输出(Output)。或者叫做写(Write)。

二:按照读取读取数据方式不同进行分类:
       有的流是按照字节的方式读取数据,一次读取1个字节byte,等于一次读取8个二进制位,这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件…
       有的流是按照字符的方式读取数据这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件也无法读取。

综上所述:流的分类:输入流、输出流、字节流、字符流。


3、IO流四大基类

在这里插入图片描述
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流

这四个基类都是抽象类。(abstract class)

所有的流都实现了:java.io.Closeable接口,都是可关闭的,即有close() 方法,所以我们在使用流后,记得关闭流,不然会耗费过多的资源。

所有输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush() 方法,输出流在最终输出之后要记得刷新一下,这表示将通道/管道当中剩余未输出的数据强行输出完,也就是清空管道。

注意:在java中只要"类名"是以stream结尾的都是字节流,以Reader/Writer结尾的都是字符流。


4、需掌握的流

java.io包下需要掌握的流有16

文件专属流:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter

转换流:(将字节流转换字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter

缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream

数据流专属
java.io.DataInputStream
java.io.DataOutputStream

标准输出流专属:
java.io.PrintWriter
java.io.PrintStream

对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream


5、FileInutStream

在这里插入图片描述

创建test文件
在这里插入图片描述

在这里插入图片描述

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
    
    

    public static void main(String[] args) {
    
    
        FileInputStream fis = null;

        try {
    
    
        	//路径写的是绝对路径,我的电脑是Mac book更windows不一样
            fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
            #循环读取
            while (true){
    
    
            	//开始读
                int read = fis.read();
                //如果等于-1,代表到达末尾,直接break退出
                if (read == -1){
    
    
                    break;
                }
                System.out.println(read);
                #到达末尾在进行读取,返回值为-1
                int read1 = fis.read();
                System.out.println(read1);
            }
        }catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
        	//在finally语句块当中确保流一定关闭
            if (fis == null) {
    
     //避免空指针异常
            	//关闭流的前提是:流不是空。流是null就不需要关闭了
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

上面的代码还是有蛮大问题的,即使用了循环,也还是不好,因为每次只读取一个字节,接下来教给大家读取多个字节的方法
在这里插入图片描述

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
    
    

    public static void main(String[] args) {
    
    
        FileInputStream fis = null;

        try {
    
    
            fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
            //采用bytes数组,一次读取多个字节,最多读取 "数组长度"个字节
            byte[] bytes = new byte[4];
            //这个方法返回值为:读取到的字节数量
            int read = fis.read(bytes);
            //将字节数组全部转换成字符串
            //读取多少个转换多少个,而不是全部读出
            System.out.println(new String(bytes,0,read));

            int read1 = fis.read(bytes);
            System.out.println(new String(bytes,0,read1));

        }catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (fis == null) {
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

FileInputStream完美写法

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
    
    

    public static void main(String[] args) {
    
    
        FileInputStream fis = null;

        try {
    
    
            fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
            //采用bytes数组,一次读取多个字节,最多读取 "数组长度"个字节
            byte[] bytes = new byte[4];
            int readCount = 0;
            while ((readCount = fis.read(bytes)) != -1) {
    
    
                System.out.println(new String(bytes,0,readCount));
            }

        }catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (fis == null) {
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述


6、FileInputStream其他方法

在这里插入图片描述

available:返回流当中剩余的没有读到的字节数量

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
    
    

    public static void main(String[] args) {
    
    
        FileInputStream fis = null;

        try {
    
    
            fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
            //还没有开始读取,这时使用available读取到的就是总字节数量
            System.out.println("总字节数量:"+fis.available());

            //读取1个
            int read = fis.read();

            //查看还可以读取的字节数量
            System.out.println(fis.available());

        }catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (fis == null) {
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

作用:在使用byte数组时可以使用available,这样就不用循环了
缺点:不适合太大的文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


7、FileOutputStream

文件字节输出流,从硬盘到内存

package io;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest {
    
    

    public static void main(String[] args) {
    
    
        FileOutputStream fos = null;

        try {
    
    
        	#如果没有改文件就创建文件
            fos = new FileOutputStream("myfile");
            //写
            byte[] b = {
    
    97,98,99,100};
            fos.write(b);

            //写完之后刷新
            fos.flush();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (fos != null) {
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }

    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

每次新写入是先清空原文件,重新写入

接下来交大家将新内容写入文本末尾处,而不是清空原文件内容
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

追加成功,原文件没有被清空

写入字符串在这里插入图片描述

在这里插入图片描述


8、FileReader

FileReader:文件字符输入流,只能读取普通文本,读取文本内容时,比较方便,快捷。

package io;


import java.io.*;

public class FileReaderTest {
    
    

    public static void main(String[] args) {
    
    
        FileReader fr = null;

        try {
    
    
            fr = new FileReader("myfile");
            //每次读取4个字符
            char[] chars = new char[4];

            int readCOunt = 0;
            while ((readCOunt = fr.read(chars)) != -1) {
    
    
                System.out.println(new String(chars,0,readCOunt));
            }
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

在这里插入图片描述


9、FileWriter

文件字符输出流,写。只能输出普通文本。

package io;


import java.io.*;

public class FileWriterTest {
    
    

    public static void main(String[] args) {
    
    
         FileWriter fw = null;

        try {
    
    
            fw = new FileWriter("file");

            char[] chars = {
    
    '我','是','皮','皮','虾'};
            fw.write(chars);
            fw.flush();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if (fw != null) {
    
    
                try {
    
    
                    fw.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


10、带缓冲区的字符流

BufferedReader:带有缓冲区的字符输入流,使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲

package io;


import java.io.*;

public class BufferedReaderTest {
    
    

    public static void main(String[] args) throws Exception {
    
    
        FileReader reader = new FileReader("file");

		//BufferedReader:包装流,使用BufferedReader把FileReader包装起来
        BufferedReader br = new BufferedReader(reader);
        //readLine一次读取一行
        String s = br.readLine();
        System.out.println(s);

        //关闭流
        br.close();

    }
}

在这里插入图片描述

在这里插入图片描述

对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭,源代码参考如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

11、转换流

InputStreamReader

package io;


import java.io.*;

public class BufferedReaderTest {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //字节流
        FileInputStream in = new FileInputStream("file");

        //转换流
        InputStreamReader reader = new InputStreamReader(in);

        //只能传字符流,不能传字节流
        BufferedReader br = new BufferedReader(reader);

        String str = null;
        while ((str = br.readLine()) != null){
    
    
            System.out.println(str);
        }
        
    }
}

在这里插入图片描述

合并写法

//合并写法
BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream("file")));

String str = null;
while ((str = file.readLine()) != null){
    
    
    System.out.println(str);
}

在这里插入图片描述

执行结果一样的

BufferedWriter

带缓冲区的字符输出流

package io;


import java.io.*;

public class BufferedReaderTest {
    
    

    public static void main(String[] args) throws Exception {
    
    
		//带有缓冲区的字符输出流
        BufferedWriter ppx = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("ppx")));
		//开始写
        ppx.write("hello 皮皮虾");
        ppx.write("\n");
        ppx.write("666");
        //刷新
        ppx.flush();
		//关闭
        ppx.close();

    }
}

在这里插入图片描述


博主会持续更新,有兴趣的小伙伴可以点赞、关注和收藏下哦,你们的支持就是我创作最大的动力!

Java学习路线目录索引

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/llllllkkkkkooooo/article/details/108546738