IO流知识点[总结]

1. IO 流原理及流的分类

1.1 Java IO 流原理

image-20230920171824486
在这里插入图片描述

1.2 流的分类

image-20230920171814812

1.3 IO流体系图-常用的类

  • IO流体系图

image-20230920171755397

  • 文件 VS 流

image-20230920171852058

image-20230920172049681

image-20230920172333074

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 介绍

image-20230921161032822

2.1 FileReader 相关方法

image-20230921162003675

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 常用方法

image-20230921162041440

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)

image-20230921170156197

  • 节点流和处理流一览图

image-20230921170305638

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

image-20230921170347659

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

image-20230921193219867

image-20230921193231473

3.3 介绍 BufferedOutputStream

image-20230921193310519

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

image-20230921195936893

image-20230921195949681

3.5 对象流介绍

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

ObjectOutputStream 提供 序列化功能

ObjectInputStream 提供 反序列化功能

image-20230921200112013

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();
    }
}

image-20230921203945811

3.6 标准输入输出流

image-20230921205130265

image-20230921205141323

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

image-20230921211436590

image-20230921211449023

5. Properties 类

image-20230922104509056

image-20230922104522974

image-20230922104530102

  • 应用案例

image-20230922104545918

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很抱歉,作为文本AI助手,我无法绘制思维导图。但是,我可以为您提供一个简要的java IO知识总结。 Java IO是Java中用于处理输入和输出的机制。它提供了一种有效的方式来读取和写入数据,以及与文件、网络和其他设备进行交互。 Java IO包括字节和字符两种类型。字节以字节为单位进行操作,适用于处理二进制数据。而字符以字符为单位进行操作,适用于处理文本数据。 常用的字节包括InputStream和OutputStream类,用于读取和写入字节数据。常用的字符包括Reader和Writer类,用于读取和写入字符数据。可以通过使用字节和字符的组合来实现不同类型数据的读写操作。 在Java IO中,还有一些特殊的,如缓冲、转换、对象等。缓冲提供了缓冲区来提高IO性能。转换用于处理字符编码和解码。对象用于对Java对象进行读写操作。 此外,Java IO还包括一些常用的类和方法,如File类用于处理文件和目录,RandomAccessFile类用于对文件进行随机访问,FileInputStream和FileOutputStream类用于读写文件等。 通过组合和使用不同类型的和类,您可以实现各种复杂的IO操作,如读写文件、网络通信、序列化对象等。 希望这个简要总结对您有所帮助。如果您有任何更具体的问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [万字长文+思维导图帮你梳理 Java IO ,还学不会你来打我(值得收藏)](https://blog.csdn.net/a1405/article/details/116766237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xjz_2002

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

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

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

打赏作者

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

抵扣说明:

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

余额充值