Java基础之详谈IO流

前言😀

  • 这次时跟着B站的动力节点视频学习的
  • 当记录个笔记方便日后学习
  • 同时将重点内容整理一下放在这里。

一、对IO的了解✌

1.1IO流的分类

  • 有多种分类方式:
  • 一种方式时按照流的方向进行分类:以内存作为参照物
    • 往内存中去,叫做输入(Input),或者叫读(Read)
    • 从内存中出来,叫做输出(Output),或者叫写(Write)
  • 另一种方式是按照读取数据方式不同进行分类:
    • 字节流:有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。这种流是万能的,什么类型的文件都可以读取。
    • 字符流:有的流是按照字符方式读取数据的,一次读取一个字符,方便读取普通文本文件而存在的。不能读取图片、声音、视频等文件。
  • 综上所述:流的分类
  • 输入流、输出流
  • 字节流、字符流

1.2Java IO流四大家族

  • java.io.InputStream字节输入流
  • java.io.OutputStream字节输出流
  • java.io.Reader字符输入流
  • java.io.Writer字符输出流
  • 注意:在java中只要类名以"Stream"结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。
  • 所有的流都实现了java.io.Closeable接口,都是可关闭的,都有close()方法。
  • 所有的输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。养成一个好习惯,输出流在最后一定要flush()刷新一下,这个刷新表示将管道当中剩余未输出的数据强行输出完,清空管道。
  • 如果没有flush()可能会导致丢失数据。

1.3java.io包下需要掌握的流

  • 文件专属:
    • java.io.FileInputStream
    • java.io.FileOutputStream
    • java.io.FileReader
    • java.io.FileWrite

  • 转换流:(将字节流转换成字符流)
    • 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.ObjectInputStream
    • java.io.ObjectOutputStream

  • 标准输出流
    • java.io.PrintWriter
    • java.io.PrintStream

二、java.io.FileInputStream✌

2.1如何使用FileInputStream

/*
*java.io.FileInputStream:
* 1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
* 2、字节的方式,完成输入的操作,完成读的操作(硬盘--->内存)
*/
public class Test1 {
    public static void main(String[] args) {
        FileInputStream file = null;
        try {
            //创建文件字节输入流对象
            //idea会自动把\编辑\\。一个\表示转义
            file = new FileInputStream("D:\\demo.txt");
            //开始读
            int readData = 0;
            while((readData = file.read()) != -1)
                System.out.println((char) readData);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(file != null) {//关闭流
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  • 这是文件中字节流读取指针移动的方式。
            file = new FileInputStream("D:\\demo.txt");//这是使用byte数组一次性读取,效率更高
            byte[] bytes = new byte[4];
            int read = 0;
            while((read = file.read(bytes)) != -1) {//返回的是读取数量
                System.out.println(new String(bytes,0,read));
            }

2.2FileInputStream常用方法

  • int available():返回流当中剩余的没有读到的字节数量
  • 我们可以直接上来查看文件中的字节数量file.available(),然后将我们的byte数组长度设为这个,这样就不必使用循环了,一次性全部读完。但是此方式并不适合太大的文件。
  • long skip(long n):跳过几个字节不读

三、java.io.FileOutputStream✌

3.1如何使用FileOutputStream

public class FileOutputStream02 {
    public static void main(String[] args) {
        FileOutputStream file = null;
        try {
            //文件不存在时,会自动新建。在文件末尾追加、
            //如果没有true,则会将文件清空后写入
            file = new FileOutputStream("D:\\demo.txt",true);
            byte[] bytes = new byte[]{99,100,101};
            file.write(bytes);//将bytes数组全部写出
            file.flush();
            //学会了输入流,这个输出流大同小异,比较简单了
        }

3.2文件复制

-先看图👇

public class FileOutputStream02 {
    public static void main(String[] args) {
        FileInputStream fileInput = null;
        FileOutputStream fileOutput = null;
        try {
            fileInput = new FileInputStream("D:\\demo.txt");
            fileOutput = new FileOutputStream("D:\\de.txt");
            byte[] bytes = new byte[1024*1024];
            int read = 0;
            while((read = fileInput.read(bytes)) != -1) {
                fileOutput.write(bytes,0,read);//读了多少就写多少
            }
            fileOutput.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fileInput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fileOutput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四、其他流的使用✌

4.1FileReader和FileWriter的使用

  • 这两个时字符输入输出流
  • 用法和上面没有什么区别,只不过是把数组byte变成了char型的,其他无异。
  • 输出流时支持直接使用字符串。out.write("我是渔夫会扎蛙!");

4.2BufferedReader缓冲流的使用

public class BufferedReaderText01 {
    public static void main(String[] args) throws Exception {
        FileReader fileReader = new FileReader("D:\\demo.txt");
        //当一个流的构造方法中需要一个流时,这个被传递进来的流叫做:节点流
        //外部负责包装的这个流叫做:包装类/处理流
        //这个FileReader就是一个节点流。BufferedReader就是一个包装流
        BufferedReader br = new BufferedReader(fileReader);

        String firstLine = br.readLine();
        System.out.println(firstLine);
        //对于包装流来说,只需要关系包装流,里面的节点流会自动关闭
        br.close();
    }
}

4.3BufferWriter缓冲流的使用

public class BufferedWriterTest01 {
    public static void main(String[] args) throws IOException {
        BufferedWriter out = new BufferedWriter(new FileWriter("D:\\demo.txt"));
        //将字节流转成字符流使用
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\demo.txt")));
        out.write("\n");
        out.write("hello world!");
        out.flush();//记得刷新管道
        out.close();//记得关闭

    }
}

4.4标准输出流PrintStream

public class PrintStreamTest {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream log = new PrintStream(new FileOutputStream("log"));
        System.setOut(log);//将不在控制台输出,改变了输出方向,输出到log文件中
        System.out.println("hello world!");
        System.out.println("hello lllxxxx!");
    }
}

五、java.io.File类✌

5.1了解File类

  • File类并不是流,所以不能完成读和写的操作
  • File对象代表:文件和目录路径名的抽象表示形式
  • 一个File对象有可能是目录,也有可能是文件
  • 需要掌握File类中常用的方法
public class FileTest01 {
    public static void main(String[] args) {
        //创建一个File对象
        File file = new File("D:\\demo.txt");
        //判断是否存在
        System.out.println(file.exists());
        file.createNewFile();//以文件的方式创建
        file.mkdir();//以目录的形式创建
    }
}

5.2File常用方法

  • 获取文件名:getName()
  • 判断是否是一个文件:isFile()
  • 判断是否是一个目录:isDirectory()
  • 获取文件最后一个修改时间:lastModified()//从1970年到现在的总毫秒数
  • 获取文件大小:length()

六、序列化和反序列化✌

  • 参与序列化和反序列化的对象,必须实现Serializable接口
public class Student implements Serializable {
//Serializable起到一个标记的作用,java虚拟机看到这个类实现了这个接口,会有不一样的感觉😍
    private int no;
    private String name;

    public Student() {
    }

    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}
public class ObjectOutputStreamTest01 {
    public static void main(String[] args) throws Exception {
        Student lx = new Student(1, "lx");
        //序列化
        //有个关键字transient表示游离的,不支持序列化
        ObjectOutputStream students = new ObjectOutputStream(new FileOutputStream("students"));
        //序列化对象
        students.writeObject(lx);
        students.flush();
        students.close();
    }
  • 实现了Serializable这个接口,java虚拟机会自动提供给你一个序列号。用于区分类
  • 缺陷:就是不能更改代码,因为只要修改代码,则将会重新编译,则java虚拟机会认为这是个全新的类。
  • 建议:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,即使修改了类中的内容,java虚拟机也不会认为这是全新的类。

七、IO和Properties的联合使用✌

  • IO流:文件的读和写
  • Properties:是一个Map集合,key和value都是String类型
  • 以后我们使用数据库时,会使用此方法。
public class IoPropertiesTest {
    public static void main(String[] args) throws IOException {
        FileInputStream file = null;
        file = new FileInputStream("D:\\demo.txt");
        //新建一个Map集合
        Properties properties = new Properties();
        //文件中的数据顺着管道流加载到Map集合中,其中等号=左边做key,右边做value
        properties.load(file);
        //通过key获取value
        String username = properties.getProperty("username");
        System.out.println(username);
    }
}
  • 我们通常将存信息的文件称为配置文件
  • 并且当配置文件中的内容格式是key1=value时候,我们把这种配置文件叫做属性配置文件。
  • Java规范中要求:属性配置文件建议以.properties结尾,但不不是必须的。

六、结尾

  • 对于JavaIO内容就总结这么多,若想深入学习等待后续更新,基础部分掌握这些足矣。如果有不足之处,希望大家多多包涵,多多支持。如果有不懂的地方可以直接私信问我,欢迎来访!
  • 我将会继续更新关于Java的学习知识,感兴趣的小伙伴可以关注一下。
  • 文章写得比较走心,用了很长时间,绝对不是copy过来的!
  • 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
  • 😎你的点赞与关注,是我努力前行的无限动力。🤩
posted @ 2022-04-08 17:54  lx-Meteor  阅读(74)  评论(0编辑  收藏  举报