十五、IO流(一)

一、File类

1.1 File类概述和构造方法

  • File类介绍

    • 它是文件和目录路径名的抽象表示
    • 文件和目录是可以通过File封装成对象
    • 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。
      • 它可以是存在的,也可以是不存在的
      • 将来是要通过具体的操作把这个路径的内容转换为具体存在的
  • File类的构造方法

    方法名说明
    File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
    File(String parent, String child)将父路径名字符串和子路径名字符串进行拼接,创建新的File实例
    File(File parent, String child)将父抽象路径名和子路径名字符串进行拼接,创建新的File实例
  • 示例代码

import java.io.File;

public class Demo01 {
    public static void main(String[] args) {
        // File(String   pathname)
        // 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
        String s1 = "E:\\java";
        File file1 = new File(s1);
        System.out.println(file1);  // E:\java

        // File(String   parent, String child)
        // 从父路径名字符串和子路径名字符串创建新的File实例
        String s2 = "java.txt";
        File file2 = new File(s1, s2);
        System.out.println(file2);  // E:\java\java.txt

        // File(File   parent, String child)
        // 从父抽象路径名和子路径名字符串创建新的File实例
        String s3 = "a.txt";
        File file3 = new File(file1, s3);
        System.out.println(file3);  // E:\java\a.txt
    }
}

1.2 绝对路径和相对路径

  • 绝对路径

    • 是一个完整的路径,从盘符开始
  • 相对路径

    • 是一个简化的路径,相对当前项目下的路径
    • 注意这里是当前项目下,不是当前模块下

1.3 File类创建功能

  • 方法分类

    方法名说明
    public boolean createNewFile()当具有该名称(路径+文件名)的文件不存在时,创建一个由该抽象路径名命名的新空文件
    public boolean mkdir()创建由此抽象路径名命名的目录,只能创建单级目录
    public boolean mkdirs()创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
  • 示例代码

import java.io.File;
import java.io.IOException;

public class Demo02 {
    public static void main(String[] args) throws IOException {
        // public boolean createNewFile()
        // 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
        /*
            说明:
            1、如果文件存在,则创建失败,返回false
            2、如果文件不存在,创建成功,返回true
            3、创建时不管文件是否有后缀名
         */
        File file1 = new File("E:\\java.txt");
        boolean result = file1.createNewFile();
        System.out.println(result);  // true
        boolean result2 = file1.createNewFile();
        System.out.println(result2);  // false

        // public boolean mkdir()
        // 创建由此抽象路径名命名的目录
        /*
            说明:
            1、只能创建单级文件夹,不能创建多级文件夹或创建文件,所以了解即可
         */
        File file2 = new File("E:\\java");
        boolean result3 = file2.mkdir();
        System.out.println(result3);

        // public boolean mkdirs()
        // 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
        /*
            说明:
            1、既可以创建多级文件夹,也可以创建单级文件夹
            2、不管有没有后缀,只能创建文件夹
         */
        File file3 = new File("E:\\hello\\world");
        boolean result4 = file3.mkdirs();
        System.out.println(result4);
    }
}

1.4 File类删除功能

  • 方法分类

    方法名说明
    public boolean delete()删除由此抽象路径名表示的文件或目录
  • 示例代码

import java.io.File;
import java.io.IOException;

public class Demo03 {
    public static void main(String[] args) throws IOException {
        // public boolean   delete()
        // 删除由此抽象路径名表示的文件或目录
        /*
            说明:
            1、删除的文件或空文件夹不经过回收站
            2、如果是文件或空文件夹,则可直接删除
            3、如果删除的文件夹非空,则需先进入把内容都删除,然后删除空文件夹
         */
        // 删除文件
        File file = new File("E:\\java.txt");
        boolean result1 = file.createNewFile();
        boolean result2 = file.delete();
        System.out.println(result1);
        System.out.println(result2);

        // 删除目录
        File file1 = new File("E:\\hello\\world");
        boolean result3 = file1.mkdirs();
        System.out.println(result3);
        // System.out.println(file1.delete());
        File file2 = new File("E:\\hello");
        System.out.println(file2.delete());  // hello文件夹不为空


    }
}


1.5 File类判断和获取功能

  • 判断功能

    方法名说明
    public boolean isDirectory()测试此抽象路径名表示的File是否为目录
    public boolean isFile()测试此抽象路径名表示的File是否为文件
    public boolean exists()测试此抽象路径名表示的File是否存在
  • 获取功能

    方法名说明
    public String getAbsolutePath()返回此抽象路径名的绝对路径名字符串
    public String getPath()将此抽象路径名转换为路径名字符串
    public String getName()返回由此抽象路径名表示的文件或目录的名称
    public File[] listFiles()返回此抽象路径名表示的目录中的文件和目录的File对象数组
  • 示例代码

import java.io.File;
import java.io.IOException;

public class Demo04 {
    public static void main(String[] args) throws IOException {
        File file = new File("demo\\dir1");
        file.mkdirs();
        File file2 = new File("demo\\file1");
        file2.createNewFile();
        // public boolean isDirectory()
        // 测试此抽象路径名表示的File是否为目录
        System.out.println(file.isDirectory());
        
        // public boolean isFile()
        // 测试此抽象路径名表示的File是否为文件
        System.out.println(file2.isFile());
        
        // public boolean exists()
        // 测试此抽象路径名表示的File是否存在
        System.out.println(file.exists());

        // public String getAbsolutePath()
        // 返回此抽象路径名的绝对路径名字符串
        System.out.println(file.getAbsolutePath());

        // public String getPath()
        // 将此抽象路径名转换为路径名字符串
        System.out.println(file.getPath());

        // public String getName()
        // 返回由此抽象路径名表示的文件或目录的名称
        System.out.println(file.getName());

        // public File[] listFiles()
        // 返回此抽象路径名表示的目录中的文件和目录的File对象数组
        File file3 = new File("E:\\");
        File[] files = file3.listFiles();
        for (File file1 : files) {
            System.out.print(file1 + " ");
        }
    }
}

  • 总结

    • File获取和判断方法

      • 判断是否为目录/文件夹

      • 判断是否存在exists

      • 获取文件和文件夹的名字

    • File[] listFiles()进入文件夹,获取所有的文件和目录的File对象,并用数组返回(包含隐含文件

      • 当调用者是一个文件是,调用会返回null

      • 当调用者是一个空文件夹是,调用会返回一个长度为0的数组

      • 当调用着是一个有权限才能进入的文件夹时,也会返回null


1.6 File类练习一

  • 案例需求

    • 在当前模块下的aaa文件夹中创建一个a.txt文件
  • 实现步骤

    • 创建File对象,指向当前模块下的aaa文件夹
    • 判断aaa文件夹是否存在,如果不存在则创建
    • 创建File对象,指向aaa文件夹下的a.txt文件
    • 创建这个文件
  • 代码实现

import java.io.File;
import java.io.IOException;

public class Test01 {
    public static void main(String[] args) throws IOException {
        // 创建File对象,指向aaa文件夹
        File file = new File("filemodule\\aaa");
        // 如果不存在则创建
        if(!file.exists()){
            file.mkdirs();
        }
        // 创建File对象,指向aaa文件夹下的文件
        File file2 = new File(file, "a.txt");
        file2.createNewFile();  // 存在则不创建
    }
}

1.7 File类练习二

  • 案例需求

    • 删除一个多级文件夹
  • 实现步骤

    • 定义一个方法,接收一个File对象
    • 遍历这个File对象,获取它下边的每个文件和文件夹对象
    • 判断当前遍历到的File对象是文件还是文件夹
    • 如果是文件,直接删除
    • 如果是文件夹,递归调用自己,将当前遍历到的File对象当做参数传递
    • 参数传递过来的文件夹File对象已经处理完成,最后直接删除这个空文件夹
  • 代码实现

import java.io.File;

public class Test02 {
    public static void main(String[] args) {
        // 创建file对象,指向准备好的文件夹
        File file = new File("C:\\Users\\Administrator\\Desktop\\aaa");
        if (file.exists()) {
            deleteDir(file);
        }
    }

    public static void deleteDir(File file) {
        // 返回文件夹内所有文件和文件夹
        File[] files = file.listFiles();
        for (File file1 : files) {
            // 如果是文件,直接删除
            if (file1.isFile()) {
                file1.delete();
            } else {
                // 如果是文件夹,递归调用
                deleteDir(file1);
            }
        }
        // 删除空文件夹
        file.delete();
    }
}

1.8 File类练习三

  • 案例需求
    • 统计一个文件夹中每种文件的个数并打印
  • 代码实现
import java.io.File;
import java.util.HashMap;

public class Test03 {
    public static void main(String[] args) {
        File file = new File("E:\\hello");
        HashMap<String, Integer> hashMap = new HashMap<>();
        getCount(hashMap, file);
        System.out.println(hashMap);
    }

    public static void getCount(HashMap<String, Integer> hashMap, File file) {
        File[] files = file.listFiles();
        for (File file1 : files) {
            // 如果是文件,按.分隔
            if (file1.isFile()) {
                String name = file1.getName();
                // split中\和.有特殊含义(正则),要用\\.来转义
                String[] split = name.split("\\.");
                if (split.length == 2) {  // 防止没有后缀或者文件名中有多个.
                    if (hashMap.containsKey(split[1])) {  
                        // 存在则计数加一
                        Integer count = hashMap.get(split[1]);
                        count++;
                        hashMap.put(split[1], count);
                    } else {
                        // 不存在则添加进hashMap
                        hashMap.put(split[1], 1);
                    }
                }
            }
            if (file1.isDirectory()) {
                // 如果是文件夹则递归调用
                getCount(hashMap, file1);
            }
        }
    }
}

二、字节流

2.1 IO流概述和分类

  • IO流介绍
    • IO:输入/输出(Input/Output)
    • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
    • IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制、文件上传、文件下载
  • IO流的分类
    • 按照数据的流向
      • 输入流:读数据
      • 输出流:写数据
    • 按照数据类型来分
      • 字节流
        • 字节输入流
        • 字节输出流
      • 字符流
        • 字符输入流
        • 字符输出流
  • IO流的使用场景
    • 如果操作的是纯文本文件,优先使用字符流
    • 如果操作的是图片、视频、音频等二进制文件,优先使用字节流
    • 如果不确定文件类型,优先使用字节流。字节流是万能的流

2.2 字节流写数据

  • 字节流抽象基类

    • InputStream:这个抽象类是表示字节输入流的所有类的超类
    • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    • 子类名特点:子类名称都是以其父类名作为子类名的后缀
  • 字节输出流

    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件
  • 使用字节输出流写数据的步骤

    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法write(int b)
    • 释放资源close()(关闭此文件输出流并释放与此流相关联的任何系统资源)
  • 示例代码

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo05 {
        public static void main(String[] args) throws IOException {
            FileOutputStream fos = new FileOutputStream("demo\\fos.txt");
            // void write(int b)
            // 将指定的字节写入此文件输出流,一次写一个字节数据
            fos.write(98);
            // void close():关闭此文件输出流并释放与此流相关联的任何系统资源。
            fos.close();
        }
    }
    

2.3 字节流写数据的三种方式

  • 写数据的方法分类

    方法名说明
    void write(int b)将指定的字节写入此文件输出流 一次写一个字节数据
    void write(byte[] b)b.length字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
    void write(byte[] b, int off, int len)len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据(注意len是几个字节,不是索引)
  • 示例代码

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo06 {
        public static void main(String[] args) throws IOException {
            // void write(byte[] b)
            // 将 b.length字节从指定的字节数组写入此文件输出流
            FileOutputStream fos = new FileOutputStream("demo\\fos.txt");
            byte[] bytes = {1, 2, 3, 4, 5, 6};
            fos.write(bytes);
    
            // void write(byte[] b, int off, int len)
            // 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据
            byte[] bytes1 = "abcde".getBytes();
            fos.write(bytes1, 0, 3);
            fos.close();
    
        }
    }
    

2.4 字节流写数据的两个小问题

  • 字节流写数据如何实现换行

    • windows:\r\n
    • linux:\n
    • mac:\r
  • 字节流写数据如何实现追加写入

    • public FileOutputStream(String name,boolean append)
    • 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾(最后一个字符后,默认不换行)而不是开头
  • 示例代码

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo07 {
        public static void main(String[] args) throws IOException {
            // 实现字节流写数据的追加
            FileOutputStream fos = new FileOutputStream("demo\\fos.txt", true);
            // 写数据并换行
            fos.write("aaa".getBytes());
            fos.write("\r\n".getBytes());
            fos.write("aaa".getBytes());
            fos.write("\r\n".getBytes());
    
            // 释放资源
            fos.close();
    
        }
    }
    

2.5 字节流写数据加异常处理

  • 异常处理格式

    • try-catch-finally

      try{
      	可能出现异常的代码;
      }catch(异常类名 变量名){
      	异常的处理代码;
      }finally{
      	执行所有清除操作;
      }
      
    • finally特点

      • finally控制的语句一定会执行,除非JVM退出
  • 示例代码

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo08 {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            // 加入finally来实现释放资源
            try {
                fos = new FileOutputStream("day18\\fos.txt");
                fos.write("hello".getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 若FileOutputStream对象未成功创建则不需要关闭资源
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

2.6 字节流读数据(read()一次读一个字节数据)

  • 字节输入流

    • FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
  • 字节输入流读取数据的步骤

    • 创建字节输入流对象
    • 调用字节输入流对象的读数据方法
    • 释放资源
  • 示例代码

    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class Demo09 {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("demo\\fos.txt");
            int read = 0;
            // fis.read():读数据
            // 当读取的数据为-1则停止读取
            while ((read = fis.read()) != -1) {
                System.out.println((char) read);
            }
            // 释放资源
            fis.close();
        }
    }
    
    

2.7 字节流复制文件

  • 实现步骤

    • 复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
  • 代码实现

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo10 {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("E:\\hello\\world.txt");
            FileOutputStream fos = new FileOutputStream("demo\\world.txt");
            // 读取数据,循环写入
            int read;
            while ((read = fis.read()) != -1) {
                fos.write(read);
            }
    
            // 释放资源
            fos.close();
            fis.close();
        }
    }
    

2.8 字节流读数据(一次读一个字节数组数据)

  • 一次读一个字节数组的方法

    • public int read(byte[] b):从输入流读取最多b.length个字节的数据
    • 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数
      在这里插入图片描述
  • 示例代码

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo11 {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("demo\\fos.txt");
            FileOutputStream fos = new FileOutputStream("E:\\hello\\world.txt");
            byte[] bytes = new byte[1024];
            int len;  // 本次读到的有效字节个数
            // 循环读取
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
            fis.close();
            fos.close();
        }
    }
    

三、字节缓冲流

3.1 字节缓冲流构造方法

  • 字节缓冲流介绍

    • BufferOutputStream:该类实现缓冲输出流。
      • 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
    • BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组
      • 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
  • 构造方法:

    方法名说明
    BufferedOutputStream(OutputStream out)创建字节缓冲输出流对象
    BufferedInputStream(InputStream in)创建字节缓冲输入流对象
    • 注:不能使用字符串传参构造,必须传递字节流对象(因为字节缓冲流仅仅在内存中提供一个数组缓冲区)
  • 示例代码

    import java.io.*;
    
    public class Demo12 {
        public static void main(String[] args) throws IOException {
            // BufferedOutputStream(OutputStream out)
            // 创建字节缓冲输出流对象
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("demo\\fos.txt"));
            // 写数据并释放
            bos.write("hello\r\n".getBytes());
            bos.write("world\r\n".getBytes());
            bos.close();
    
            // BufferedInputStream(InputStream in)
            // 创建字节缓冲输入流对象
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day18\\fos.txt"));
            // 一次读取一个字节数组数据
            byte[] bytes = new byte[1024];
            int len;
            while ((len = bis.read(bytes)) != -1) {
                System.out.print(new String(bytes, 0, len));
            }
            // 释放
            bis.close();
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值