shanX
文章31
标签17
分类9
JAVA-IO流

JAVA-IO流

IO 流

流的概念

内存与存储设备之间传输数据的通道

image-20210409191717082

流的分类

按方向【重点】

  1. 输入流:将<存储设备>中的内容读到<内存>中;

  2. 输出流:将<内存>中的内容写到<存储设备>中;

    文件 ———输入流———–> 程序 ———输出流———–>文件

按单位

  1. 字节流:以字节流为单位,可以读写所有数据;
  2. 字符流:以字符为单位,只能读写文本数据;

按功能

  1. 节点流:具有实际传输数据的读写功能;
  2. 过滤流:在节点流的基础之上增强功能;

字节流

字节流的父类(抽象类):

  1. InputStream 字节输入流

    //InputStream 字节输入流
    public int read(){}
    public int read(byte[] b){}
    public int read(byte[] b, int off, int len){}
    
  2. OutStream 字节输出流

    // OutputStream 字节输出流
    public void write(int n){}
    public void write(byte[] b){}
    public void write(byte[] b, int off, int len){}
    

文件字节流

输入流:

        // 创建文件输出流对象
        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-    workspace\\kuangshen_java\\IO流\\src\\aaa.txt");

        // 单个字节读取文件
        int data = 0;
        while ((data=fis.read()) != -1) {
            System.out.print((char) data);
        }
        // 指定读取个数,每次三个
        byte[] buf = new byte[3];
        int count = fis.read(buf);
        System.out.println(new String(buf));
        System.out.println(count);

        int count2 = fis.read(buf);
        System.out.println(new String(buf));
        System.out.println(count2);
        // 循环读取
        byte[] buf = new byte[1024];
        int count = 0;
        while ((count=fis.read(buf))!=-1) {
            System.out.println(new String(buf, 0, count));
        }
        //关闭
        fis.close();

输出流:

        //创建文件输出流对象;
        FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\bbb.txt");
        //写入文件
        fos.write(97);
        fos.write('b');
        fos.write('c');
         //写入字符串
        String str = "helloworld";
        fos.write(str.getBytes());
        fos.close();

图片复制案例

        //创建流
        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.jpg");
        FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\ccc.jpg");

        ////边读边写
        byte[] b = new byte[1024];
        int count = 0;
        while ((count = fis.read(b)) != -1) {
            fos.write(b, 0, count);
        }

        //关闭
        fis.close();
        fos.close();

字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream

提高 IO 效率,减少访问磁盘次数;

数据存储在缓冲区中,flush 是将缓冲区的内容写入文件中,也可以直接 close

        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        //创建缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(fis);
        //读取
        int data = 0;
        while ((data=bis.read())!=-1){
            System.out.print((char) data);
        }

        //关闭
        bis.close();
        fis.close();

缓冲流读文件:

        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        //创建缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(fis);
        //读取
//        int data = 0;
//        while ((data=bis.read())!=-1){
//            System.out.print((char) data);
//        }
        byte[] buf = new byte[1024];
        int count = 0;
        while ((count = bis.read(buf))!=-1) {
            System.out.print(new String(buf, 0, count));
        }

        //关闭
        bis.close();
        fis.close();

缓冲流写文件:

        //创建缓冲流对象
        FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\ddd.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //写入文件
        for (int i = 0; i < 5; i++) {
            bos.write("theworllllld\n".getBytes()); //写入缓冲区,缓冲区默认大小为8k
            bos.flush(); // 刷新到硬盘
        }

        //关闭,bos.close();会自动调用 bos.flush(), 但异常中断的话会写入失败
        bos.close();

对象流

ObjectOutputStream / ObjectInputStream

  1. 增强了缓冲区功能
  2. 增强了读写 8 种基本数据类型和字符串的功能
  3. 增强了读写对象的功能
    1. readObject() 从流中读取一个对象
    2. writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程称为序列化(写入)、反序列化(读取)

序列化

        // 1. 创建对象流
        FileOutputStream fos = new     FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\st.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        // 2. 序列化(写入操作)
        Student zhangsan = new Student("zs", 20);
        oos.writeObject(zhangsan);
        // 3. 关闭
        oos.close();

反序列化

        // 1. 创建对象流
        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\st.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        // 2. 读取文件(反序列化)
        Student s = (Student)ois.readObject();
        // 3. 关闭
        ois.close();

注意事项:

  1. 某个类要想序列化必须实现 Serializable 接口;
  2. 序列化类中对象属性要求实现 Serializable 接口;
  3. 序列化版本号 ID例如 :private static final long serialVersionUID = -8318741215394696905L;,保证序列化的类和反序列化的类是同一个类;
  4. 使用 transient 修饰属性,这个属性就不能序列化;
  5. 静态属性不能序列化;
  6. 序列化多个对象,可以借助集合来实现;

字符流

// 传统字节流读取
    public static void main(String[] args) throws Exception {
            // 1. 创建FileInputStream对象
            FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
            // 2. 读取
            int data = 0;
            while((data = fis.read()) != -1){
                System.out.print(((char)data));
            }
            // 3. 关闭
            fis.close();
    }

字符流的父类

reader 字符输入流
  1. public int read(){}
  2. public int read(char[] c){}
  3. public int read(char[] b, int off, int len){}
public static void main(String[] args) throws Exception {
        // 1. 创建FileReader 文件字符输入流
        FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        // 2. 读取
        // 2.1 单个字符读取
        int data = 0;
        while((data = fr.read()) != -1){
            System.out.print((char)data);// 读取一个字符
        }

        char[] buf = new char[2];// 字符缓冲区读取
        int count = 0;
        while((count = fr.read(buf)) != -1){
            System.out.print(new String(buf, 0, count));
        }

        // 3. 关闭
        fr.close();
    }
Writer 字符输出流
  1. public void write(int n){}
  2. public void write(String str){}
  3. public void write(char[] c){}
public static void main(String[] args) throws Exception {
        // 1. 创建FileWriter对象
        FileWriter fw = new FileWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        // 2. 写入
        for(int i = 0; i < 10; i ++){
            fw.write("写入的内容");
            fw.flush();
        }
        // 3. 关闭
        fw.close();
        System.out.println("执行完毕");
    }
案例(使用上述方法进行文本复制)

不能复制图片或二进制文件,使用字节流可以复制任意文件

public static void main(String[] args) throws Exception{
        // 1. 创建
        FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        FileWriter fw = new FileWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
        // 2. 读写
        int data = 0;
        while((data = fr.read()) != -1){
            fw.write(data);
            fw.flush();
        }
        // 3. 关闭
        fw.close();
        fr.close();
    }

字符缓冲流

BufferedReader / BufferedWriter

高效读写、支持输入换行符、可一次写一行读一行;

public static void main(String[] args) throws Exception {
        // 创建缓冲流
        FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
        BufferedReader br = new BufferedReader(fr);
        // 读取
        // 1. 第一种方式
        char[] buf = new char[1024];
        int count = 0;
        while((count = br.read(buf)) != -1){
            System.out.println(new String(buf, 0, count));
        }
        // 2. 第二种方式 一行一行读取
        String line = null;
        while((line = br.readLine()) != null){
            System.out.println(line);
        }

        // 关闭
        br.close();
    }

PrintWriter

  1. 向文件中写入内容;
  2. 封装了print() / println() 方法 支持写入后换行;
  3. 支持数据原样打印;
public static void main(String[] args) throws FileNotFoundException {
        // 1 创建打印流
        PrintWriter pw = new PrintWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
        // 2 打印
        pw.println(12);
        pw.println(true);
        pw.println(3.14);
        pw.println('a');
        // 3 关闭
        pw.close();
    }

转换流

  1. 桥转换流 InputStreamReader / OutputStreamWriter
  2. 可将字节流转换为字符流
  3. 可设置字符的编码方式
public static void main(String[] args) throws Exception {
        // 1 创建InputStreamReader对象
        FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
        InputStreamReader isr = new InputStreamReader(fis, "utf-8");
        // 2 读取文件
        int data = 0;
        while((data = isr.read()) != -1){
            System.out.print((char)data);
        }
        // 3 关闭
        isr.close();
    }
 public static void main(String[] args) throws Exception {
        // 1 创建OutputStreamReader对象
        FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
        // 2 写入
        for (int i = 0; i < 10; i++) {
            osw.write("写入内容\n");
            osw.flush();
        }
        // 3 关闭
        osw.close();

    }

File 类

概念:代表物理盘符中的一个文件或者文件夹

分隔符

    //分隔符
    public static void separator() {
        System.out.println("路径分隔符" + File.pathSeparator);
        System.out.println("名称分隔符" + File.separator);
    }

文件操作

//文件操作
    public static void fileOpen() throws Exception {
        //创建文件
        File file = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\file.txt");
        if (!file.exists()) {
            boolean b = file.createNewFile();
            System.out.println("创建结果" + b);
        }else {
            System.out.println("文件已存在");
        }

        //删除文件-直接删除
//           System.out.println(file.delete());
        //删除文件 jvm退出时删除
//           file.deleteOnExit();
//           Thread.sleep(5000);


        //获取文件绝对路径
        System.out.println("文件绝对路径:" + file.getAbsolutePath());
        //获取写的路径
        System.out.println(file.getPath());
        //获取文件名称
        System.out.println(file.getName());
        //获取父目录
        System.out.println(file.getParent());
        //获取文件长度
        System.out.println(file.length());
        //获取文件创建时间
        System.out.println(new Date(file.lastModified()).toLocaleString());

        //判断
        //是否可写
        //System.out.println(file.canWrite());  //linux支持
        //是否可读
        System.out.println(file.canRead());
        //是否是文件
        System.out.println(file.isFile());
        //是否隐藏
        System.out.println(file.isHidden());

    }

文件夹操作

//文件夹操作
public static void directoryOpe() throws Exception{
        File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa\\bbb\\ccc");
        System.out.println(dir.toString());
        if (!dir.exists()) {
            //创建单级目录
//            dir.mkdir();
            //创建多级目录
            System.out.println("创建结果" + dir.mkdirs());
        }

        //删除文件
        //直接删除
//        System.out.println(dir.delete()); //只能删除空目录
        //使用jvm删除
//        dir.deleteOnExit();
//        Thread.sleep(3000);

        //获取文件夹信息
        //获取绝对路径
        System.out.println(dir.getAbsolutePath());
        //获取路径
        System.out.println(dir.getPath());
        //获取名称
        System.out.println(dir.getName());
        //获取父目录
        System.out.println(dir.getParent());
        //获取创建时间
        System.out.println(new Date(dir.lastModified()).toLocaleString());

        //判断
        //是否是文件夹
        System.out.println(dir.isDirectory());
        //是否隐藏
        System.out.println(dir.isHidden());

        //遍历文件夹
        File dir2 = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file");
        String[] dirs = dir2.list();
        //File[] dirs2 = dir2.listFiles();
        for (String s : dirs) {
            System.out.println(s);
        }

FileFilter

// fileFilter接口使用,定制方法遍历
public static void main(String[] args) {
        File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa\\bbb\\ccc");


        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.getName().endsWith(".bin")){
                    return true;
                }
                return false;
            }
        });

        for (File file : files) {
            System.out.println(file.getName());
        }

    }

递归遍历文件夹

遍历多级文件夹下的文件

public static void main(String[] args) {
        File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa");
        listDir(dir);
    }
public static void listDir(File dir) {

        File[] files = dir.listFiles();
        if (files != null && files.length>0) {
            for (File file : files) {
                if (file.isDirectory()){
                    listDir(file);
                }else {
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }

递归删除文件夹

删除多级文件夹下的文件

public static void delDir(File dir) {

        File[] files = dir.listFiles();
        if (files != null && files.length>0) {
            for (File file : files) {
                if (file.isDirectory()){
                    delDir(file);
                }else {
                    System.out.println(file.getAbsolutePath() + "删除文件" + file.delete());
                }
            }
        }
    }
本文作者:shanX
本文链接:https://rhymexmove.github.io/2021/04/09/c6fe409c993d/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可