IO流知识点学习

文章目录

    • 1. IO 流原理及流的分类
      • 1.1 Java IO 流原理
      • 1.2 流的分类
      • 1.3 IO流体系图-常用的类
    • 2. FileReader 和 FileWriter 介绍
      • 2.1 FileReader 相关方法
      • 2.2 FileWriter 常用方法
    • 3. 节点流 和 处理流(BufferedReader、BufferedWriter)
      • 3.1 节点流和处理流的区别和联系
      • 3.2 处理流-BufferedInputStream 和 BufferedOutputStream
      • 3.3 介绍 BufferedOutputStream
      • 3.4 对象流-ObjectInputStream 和 ObjectOutputStream
      • 3.5 对象流介绍
      • 3.6 标准输入输出流
      • 3.7 转换流-InputStreamReader 和 OutputStreamWriter
    • 4. 打印流-PrintStream 和 PrintWriter
    • 5. Properties 类

1. IO 流原理及流的分类

1.1 Java IO 流原理

IO流知识点学习_第1张图片
IO流知识点学习_第2张图片

1.2 流的分类

IO流知识点学习_第3张图片

1.3 IO流体系图-常用的类

  • IO流体系图

IO流知识点学习_第4张图片

  • 文件 VS 流

IO流知识点学习_第5张图片

IO流知识点学习_第6张图片

IO流知识点学习_第7张图片

package com.xjz.file.inputstream_;

import org.junit.jupiter.api.Test;

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

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 FileInputStream 的使用(字节输入流 文件 --> 程序)
 */
public class FileInputStream_ {
    public static void main(String[] args) {

    }

    /**
     * 演示读取文件..
     * 单个字符的读取,效率比较低
     * 使用 read()
     */
    @Test
    public void readFile01() {
        String filePath = "d:\\hello.txt";
        int readData = 0;
        FileInputStream fileInputStream = null;
        try {
            //创建 FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止
            //如果返回 -1,表示读取完毕
            while ((readData = fileInputStream.read()) != -1) {
                System.out.println((char) readData); //转成 char 显示
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用 read(byte[] b) 读取文件,提高效率
     */
    @Test
    public void readFile02() {
        String filePath = "d:\\hello.txt";
        //字节数组
        byte[] buf = new byte[8];
        int readLen = 0;
        FileInputStream fileInputStream = null;
        try {
            //创建 FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止
            //如果返回 -1,表示读取完毕
            //如果读取正常, 返回实际读取的字节数
            while ((readLen = fileInputStream.read(buf)) != -1) {
//                bytes - 要解码为字符的字节
//                offset - 要解码的首字节的索引
//                length - 要解码的字节数
                System.out.print(new String(buf,0,readLen)); //显示
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.xjz.file.inputstream_;

import org.junit.jupiter.api.Test;

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

/**
 * @author xjz_2002
 * @version 1.0
 */
public class FileOutputStream01 {
    public static void main(String[] args) {

    }

    /**
     * 演示使用 FileOutputStream 将数据写到文件中,
     * 如果该文件不存在,则创建该文件
     */

    @Test
    public void writeFile() {

        //创建 FileOutputStream
        String filePath = "d:\\a.txt";
        FileOutputStream fileOutputStream = null;
        try {
            //得到 FileOutputStream 对象
            //代码说明
            //1. new FileOutputStream(filePath)创建方式,当写入内容时,会覆盖原来的内容
            //2. new FileOutputStream(filePath,true)创建方式,当写入内容时,是追加到原来的内容的后面
            fileOutputStream = new FileOutputStream(filePath,true);
            //写入一个字节 write(int b);
            //fileOutputStream.write('X');
            //写入字符串 (byte[] b)
            String str = "xjz,world";
            //str.getBytes() 可以把 字符串 -》 字节数组
            //fileOutputStream.write(str.getBytes());

            /*
            write(byte[] b, int off, int len) 将 len 字节从位于偏移量 off 的指定字节数组写入此文件输出流
            */
            fileOutputStream.write(str.getBytes(),0,3);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

  • 文件拷贝
package com.xjz.file.inputstream_;

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

/**
 * @author xjz_2002
 * @version 1.0
 * 文件拷贝
 */
public class FileCopy {
    public static void main(String[] args) {
        //完成 文件拷贝,将 d:\\hnt.png 拷贝到d:\\hnt2.png
        //思路分析
        //1. 创建文件的输入流,将文件读入到程序
        //2. 创建文件的输出流,将读取到的文件数据,写入到指定的文件
        String srcFilePath = "d:\\hnt.png";
        String destFilePath = "d:\\hnt2.png";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream= null;
        try {
            fileInputStream = new FileInputStream(srcFilePath);
            fileOutputStream = new FileOutputStream(destFilePath);
            //定义一个字节数组,提高读取效率
            byte[] buf = new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf)) != -1){
                //读取到后,就写入到文件 通过 fileOutputStream
                //即 一边读,一边写
                fileOutputStream.write(buf,0,readLen);//一定要使用这个方法
            }
            System.out.println("拷贝ok~");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭输入流和输出流,释放资源
            try {
                if (fileInputStream != null){
                    fileInputStream.close();
                }
                if (fileOutputStream != null){
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2. FileReader 和 FileWriter 介绍

IO流知识点学习_第8张图片

2.1 FileReader 相关方法

IO流知识点学习_第9张图片

package com.xjz.reader_;

import org.junit.jupiter.api.Test;

import java.io.FileReader;
import java.io.IOException;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class FileReader_ {
    public static void main(String[] args) {

    }

    /**
     * 单个字符读取文件
     */
    @Test
    public void readFile01() {
        String filePath = "d:\\important.txt";
        FileReader fileReader = null;
        int data = 0;
        //1. 创建 FileReader对象
        try {
            fileReader = new FileReader(filePath);
            //循环读取 使用read,单个字符读取
            while ((data = fileReader.read())!= -1){
                System.out.print((char)data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 字符数组读取文件
     */
    @Test
    public void readFile02() {
        String filePath = "d:\\important.txt";
        FileReader fileReader = null;

        int readLen = 0;
        char[] buf = new char[8];
        //1. 创建 FileReader对象
        try {
            fileReader = new FileReader(filePath);
            //循环读取 使用read(buf),返回的是实际读取到的字符数
            //如果返回 -1,说明到文件结束
            while ((readLen = fileReader.read(buf))!= -1){
                System.out.print(new String(buf,0,readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.2 FileWriter 常用方法

IO流知识点学习_第10张图片

package com.xjz.write_;

import java.io.FileWriter;
import java.io.IOException;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class FileWriter_ {
    public static void main(String[] args) {

        String filePath = "d:\\note.txt";
        //创建 FileWriter 对象
        FileWriter fileWriter = null;
        char[] chars = {'a','b','c'};
        try {
            fileWriter = new FileWriter(filePath);//默认就是覆盖写入
            //3) write(int):写入单个字符
            fileWriter.write('X');
            //4) write(char[]):写入指定数组
            fileWriter.write(chars);
            //5) write(char[],off,len):写入指定数组的指定部分
            fileWriter.write("徐金卓".toCharArray(),0,3);
            //6) write(string):写入整个字符串
            fileWriter.write("你好,北京");
            fileWriter.write("风雨之后,定见彩虹");
            //7) write(string,off.len):写入字符串的指定部分
            fileWriter.write("上海天津",0,2);
            //在数据量大的情况下,可以使用循环操作

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //对应 FileWriter , 一定要关闭流,或者 flush 才能真正的把数据写入到文件
            //看源码就知道原因.
            if (fileWriter != null){
                try {
                    //关闭文件流,等价 flush() + 关闭
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("程序结束");
        }
    }
}

3. 节点流 和 处理流(BufferedReader、BufferedWriter)

IO流知识点学习_第11张图片

  • 节点流和处理流一览图

IO流知识点学习_第12张图片

3.1 节点流和处理流的区别和联系

IO流知识点学习_第13张图片

  • 处理流的功能主要体现在一下两个方面:

IO流知识点学习_第14张图片

package com.xjz.reader_;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 bufferedReader 使用
 */
public class BufferedReader_ {
    public static void main(String[] args) throws Exception {

        String filePath = "d:\\a.java";
        //创建 bufferedReader 对象
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取
        String line;//按行读取,效率高
        //说明
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回 null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine()) != null){
            System.out.println(line);
        }

        //关闭流,这里注意,只需要关闭 bufferedReader,因为底层会自动的去关闭 节点流
        //FileReader
        /*
        public void close() throws IOException {
            synchronized (lock) {
                if (in == null)
                    return;
                try {
                    in.close();//in 就是我们传入的 new FileReader(filePath), 关闭了.
                 } finally {
                    in = null;
                    cb = null;
                }
            }
        }
        */
        bufferedReader.close();

    }
}

image-20230921175658395

package com.xjz.write_;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 BufferedWriter 的使用
 */
public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {

        String filePath = "d:\\ok.txt";
        //创建 BufferedWriter
        //说明
        //1. new FileWriter(filePath,true) 表示以追加的方式写入
        //1. new FileWriter(filePath) 表示以覆盖的方式写入
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
        bufferedWriter.write("徐金卓1-Java开发工程师");
        bufferedWriter.newLine();//插入一个和系统相关的换行
        bufferedWriter.write("徐金卓2-Java开发工程师");
        bufferedWriter.newLine();//插入一个和系统相关的换行
        bufferedWriter.write("徐金卓3-Java开发工程师");
        bufferedWriter.newLine();//插入一个和系统相关的换行

        //说明:关闭外层流即可,传入的 new FileWriter(filePath),会在底层关闭
        bufferedWriter.close();
    }
}

image-20230921175711465

package com.xjz.write_;

import java.io.*;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class BufferedCopy_ {
    public static void main(String[] args) {

        //说明
        //1. BufferedReader 和 BufferedWriter 是安装字符操作
        //2. 不要去操作 二进制文件[声音,视频,doc,pdf],可能造成文件损坏
        //BufferedInputStream
        //BufferedOutputStream
        String srcFilePath = "d:\\a.java";
        String destFilePath = "d:\\a4.java";
        BufferedReader br = null;
        BufferedWriter bw = null;
        String line;
        try {
            br = new BufferedReader(new FileReader(srcFilePath));
            bw = new BufferedWriter(new FileWriter(destFilePath));

            //说明:readLine 读取一行内容,但是没有换行
            while ((line = br.readLine())!=null){
                //每读取一行,就写入
                bw.write(line);
                //插入一个换行
                bw.newLine();
            }
            System.out.println("拷贝完毕~");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (br != null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

3.2 处理流-BufferedInputStream 和 BufferedOutputStream

IO流知识点学习_第15张图片

IO流知识点学习_第16张图片

3.3 介绍 BufferedOutputStream

IO流知识点学习_第17张图片

image-20230921193319178

package com.xjz.outputstream_;

import java.io.*;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示使用 BufferedOutputStream 和 BufferedInputStream 使用
 * 使用他们,可以完成二进制文件拷贝
 * 思考:字节流可以操作二进制文件,可以操作文本文件吗? 当然可以
 */
public class BufferedCopy02 {
    public static void main(String[] args) {

//        String srcFilePath = "d:\\hnt.png";
//        String destFilePath = "d:\\hnt3.png";
        String srcFilePath = "d:\\a.java"; //字节流也可以处理文本文件
        String destFilePath = "d:\\a5.java";

        //创建 BufferedInputStream 和 BufferedOutputStream 对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //因为 FileInputStream 是 InputStream 子类
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));

            //循环的读取文件,并写入到 destFilePath
            byte[] buff = new byte[1024];
            int readLen = 0;
            //当返回 -1 时,就表示文件读取完毕
            while ((readLen = bis.read(buff)) != -1 ){
                bos.write(buff,0,readLen);
            }
            System.out.println("文件拷贝完毕");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //关闭流 , 关闭外层的处理流即可,底层会去关闭节点流
            try {
                if (bis != null){
                    bis.close();
                }
                if (bos != null){
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

3.4 对象流-ObjectInputStream 和 ObjectOutputStream

IO流知识点学习_第18张图片

IO流知识点学习_第19张图片

3.5 对象流介绍

功能:提供了对基本类型或对象类型的序列化和反序列化的方法

ObjectOutputStream 提供 序列化功能

ObjectInputStream 提供 反序列化功能

IO流知识点学习_第20张图片

IO流知识点学习_第21张图片

package com.xjz.outputstream_;

import java.io.*;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 ObjectOutputStream 的使用,完成数据的序列化
 */
public class ObjectOutStream_ {
    public static void main(String[] args) throws IOException {
        //序列化后,保存的文件形式,不是存文本,而是按照他的格式来保存
        String filePath = "d:\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据到 d:\\data.dat
        oos.writeInt(100); //int -> Integer(实现类 Serializable)
        oos.writeBoolean(true); //boolean -> Boolean(实现类 Serializable)
        oos.writeChar('a'); //char -> Character(实现类 Serializable)
        oos.writeDouble(9.5); //double -> Double(实现类 Serializable)
        oos.writeUTF("赵雷的朵");//String
        //保存一个 person 对象
        oos.writeObject(new Person("xjz",20));
        //关闭流
        oos.close();
        System.out.println("数据保存完毕(序列化形式)");

    }
}

//保存一个类,必须要实现它的序列化接口 Serializable
class Person implements Serializable {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

image-20230921202937815

package com.xjz.outputstream_;

import com.sun.corba.se.impl.encoding.CDROutputObject;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 ObjectInputStream 的使用,完成数据的 反 序列化
 */
public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        //1. 创建流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\data.dat"));
        //2. 读取 注意顺序(必须和反序列化顺序一致,否则读取乱码)
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());

        //person 的编译类型是 object, person 的运行类型是 Person
        Object person = ois.readObject();
        System.out.println("运行类型="+person.getClass());
        System.out.println("person信息=" + person);//底层 Object -> Person

        //这里特别重要的细节:

        //1. 如果我们希望调用 Person的方法,需要向下转型
        //2. 需要我们将 Person类的定义,拷贝到可以引用的卑职
        Person person2 = (Person) person;
        System.out.println(person2.getName()); //xjz

        //关闭流,关闭外层流即可,底层会关闭 FileInputStream 流
        ois.close();
    }
}

IO流知识点学习_第22张图片

3.6 标准输入输出流

IO流知识点学习_第23张图片

IO流知识点学习_第24张图片

3.7 转换流-InputStreamReader 和 OutputStreamWriter

package com.xjz.transformation;

import java.io.*;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示使用 InputStreamReader 转换流解决中文乱码问题
 * 将字节流 FileInputStream 转成字符流 InputStreamReader,指定编码 gbk/utf-8
 */
public class InputStreamReader_ {
    public static void main(String[] args) throws IOException {

        String filePath = "d:\\a.txt";
        //解读
        //1. 把 FileInputStream 转成 InputStreamReader
//        //2. 指定编码 gbk
//        InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
//        //3. 把 InputStreamReader 传入 BufferedReader
//        BufferedReader br = new BufferedReader(isr);

        //将 2 和 3 合在一起
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"gbk"));

        //4. 读取
        String s = br.readLine();
        System.out.println("读取内容=" + s);
        //5. 关闭外层流
        br.close();
    }
}
package com.xjz.transformation;

import java.io.*;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 OutputStreamWriter 使用
 * 把 FileOutputStream 字节流,转成字符流 OutputStreamWriter
 * 指定处理的编码 gbk/utf-8/utf8
 */
public class OutputStreamWriter_ {
    public static void main(String[] args) throws IOException {

        String filePath = "d:\\xjz.txt";
        String charSet = "utf-8";
        //把 FileOutputStream 字节流,转成字符流 OutputStreamWriter
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), charSet));
        bw.write("hello,周星驰");
        bw.close();
        System.out.println("按照" + charSet + " 保存文件成功~");
    }
}

4. 打印流-PrintStream 和 PrintWriter

image-20230921211416699

IO流知识点学习_第25张图片

IO流知识点学习_第26张图片

5. Properties 类

IO流知识点学习_第27张图片

IO流知识点学习_第28张图片

IO流知识点学习_第29张图片

  • 应用案例

image-20230922104545918

你可能感兴趣的:(后端开发基础知识点,学习)