1. File

1.1. 什么是File

  • File可以用来表示计算机中的文件或者文件夹
  • 官方定义:文件和文件夹 路径名的抽象表示形式

1.2. File的3种构造方式

  • 1File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
  • 2File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的File实例
  • 3File(File parent, String child) 从父文件对象和子路径名字符串创建新的File实例
// 构造1  参数是文件的完整路径
File file01 = new File("G:\\diany\\柯南1.mp4");
// 获取文件长度
System.out.println(file01.length());

String parentPath = "G:\\diany";
// 构造2  参1是父路径 参2 子路径
File file02 = new File(parentPath, "柯南1.mp4");
System.out.println(file02.length());

// parentFile代表的是G:\diany这个文件夹
File parentFile = new File(parentPath);
// 构造3  参1是父路径对应的File对象  参2 子路径
File file03 = new File(parentFile, "柯南1.mp4");
System.out.println(file03.length());

2. 绝对路径和相对路径

  • 绝对路径: 从盘符开始,一个文件的完整路径。
  • 相对路径 有两种情况:
    • 1 一般的理解:相对于当前文件所在目录,./表示当前文件所在目录,作为开头可以省略
    • 2 在idea中创建工程写java代码 ,相对路径指的是从工程的根目录开始的路径, ./表示工程根目录,作为开头可以省略
      • 大家要注意创建的模块和工程同名的情况
File file = new File("aaa.txt");
file.createNewFile();//在工程目录project09下创建文件

File file1 = new File("mymodule\\src\\link\\xiaomo\\test2\\bbb.txt");//在test2下创建文件
file1.createNewFile();

//这个是绝对路径 缺点是 工程如果拷贝到别的位置 就需要修改路径
File file11 = new File("C:\\Users\\WIN10\\Desktop\\mymodule\\src\\link\\xiaomo\\test2\\bbb.txt");

// ../表示上一层目录   这里会在project09的上一层的上一层 也就是java52中创建a.txt
File file2 = new File("../../a.txt");
file2.createNewFile();
  • ../表示上一层目录

  • 使用相对路径较多,方便代码的迁移

2.1. 路径的分隔符

  • 也可以使用File.separator 表示分隔符 System.out.println("a" + File.separator + "b" + File.separator + "n");
  • 单斜杠作为分隔符更通用方便 / \

    在windows中 \作为路径的分隔符,在java中用\才能表示\
    在java中也可以用/表示分隔符

代码

//相对路径
//File xiaohua1 = new File("module01\\src\\笑话大全.txt"); //   分割符\\
File xiaohua1 = new File("module01/src/笑话大全.txt"); //   
分割符/

System.out.println(xiaohua1);

2.2. File创建方法

方法名 说明
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件,如果文件存在就创建失败返回false,如果文件的路径不存在会报IOException异常
public boolean mkdir() 创建由此抽象路径名命名的目录,如果当前目录的路径不存在,会创建失败
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录

代码

  • 三种创建返回值都是布尔
  • 如果创建的文件或者目录已经存在,就不会重新创建了
public static void main(String[] args) {
    try {
        //在mymodule下创建mm1文件 如果已经存在 不会重新创建
        File file01 = new File("mymodule/mm1");
        System.out.println(file01.createNewFile());

        //mymodule01不存在 那么会报异常
        File file02 = new File("mymodule01/mm1");
        System.out.println(file02.createNewFile());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//创建文件夹  mkdir 和 mkdirs
File file01 = new File("mymodule/a");
System.out.println(file01.mkdir());

File file02 = new File("mymodule/a/b");
System.out.println(file02.mkdir());

File file03 = new File("mymodule/m/n/x");
//mkdirs可以创建 多级目录 包括不存在的父级目录
System.out.println(file03.mkdirs());

//x1.txt创建出来也是目录, 和后缀名无关
File file04 = new File("mymodule/m/n/x1.txt");
System.out.println(file04.mkdirs());

【注意】

  • createNewFile 创建的是普通文件,和后缀名是什么无关
  • mkdir和mkdirs 创建的是文件夹 和后缀名无关
  • createNewFile如果创建的文件的目录不存在,报IOException异常

2.3. 删除

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

代码

  • 删除后不会进入回收站
  • 只能删除空文件夹
        //删除后不会进入回收站
        File file = new File("hehe..txt");
        System.out.println(file.delete());

        File file1 = new File("x/y/z.mp3");
        System.out.println(file1.delete());

        //只能删除空文件夹,需要先进入文件夹 删除里面的内容,然后再删除当前文件夹
        File file2 = new File("x");
        System.out.println(file2.delete());

2.4. 判断

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

代码

File file = new File("module01\\src\\link\\xiaomo\\test2", "Demo01.java");

System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println(file.exists());

File file2 = new File("module01\\src\\link\\xiaomo\\test2");

System.out.println(file2.isFile());
System.out.println(file2.isDirectory());
System.out.println(file2.exists());

File file3 = new File("module01\\src\\link\\xiaomo\\test3");

System.out.println(file3.isFile());
System.out.println(file3.isDirectory());
System.out.println(file3.exists());

2.5. 获取

方法名 说明
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或目录的名称
public File[] listFiles() 获取当前目录里 的文件和文件夹的File对象放到一个数组里,返回数组

代码

        File file02 = new File("mymodule/a/b");

        System.out.println(file02.getAbsolutePath());//获取绝对路径 C:\Users\WIN10\Desktop\mymodule\a\b
        System.out.println(file02.getPath());//获取创建文件对象的时候传入的路径 mymodule/a/b
        System.out.println(file02.getName());//获取文件名字 b

        File file03 = new File("mymodule/m/n");
        //获取当前目录里 的文件和文件夹的File对象放到一个数组里
        File[] files = file03.listFiles();
        for (File file : files) {
            System.out.println(file.getName());
        }

File类案例一

  • 案例需求

    在当前模块下的aaa文件夹中创建一个a.txt文件

  • 实现步骤

    • 创建File对象,指向aaa文件夹
    • 判断aaa文件夹是否存在,如果不存在则创建
    • 创建File对象,指向aaa文件夹下的a.txt文件
    • 创建这个文件

代码

  • 注意aaa不存在,直接创建a.txt会报错
public class Demo01 {
    public static void main(String[] args) {
        try {
            File aaafile = new File("mymodule/aaa");
            //先判断aaa文件夹是否存在 不存在就创建
            if (!aaafile.exists()) {
                aaafile.mkdirs();
            }
            //创建a.txt的file对象
            File aFile = new File(aaafile, "a.txt");
            //创建a.txt
            aFile.createNewFile();
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

3. 案例:递归删除

3.1. 写一个方法可以删除一个File对象对应的文件或者文件夹

    /**
     * 删除file对象
     *
     * @param file 要删除的file对象 可以是文件可以是目录
     */
    public static void deleteFile(File file) {
        //1 如果file是文件  那么就直接调用delete删除
        if (file.isFile()) {
            System.out.println(file.getName()+"被删除了");
            file.delete();
        } else {
            // 2 如果是目录  就获取目录里所有的file对象
            File[] fs = file.listFiles();
            System.out.println("进入了"+file.getName());
            //3 遍历文件对象数组
            for (File f : fs) {
                //4 把f 再次调用deleteFile 传入删除
                deleteFile(f);
                //System.out.println(f);
            }
            //5 file目录里面被清空了,可以直接删除file了
            System.out.println(file.getName()+"目录里面被清空了,删除这个目录");
            file.delete();
        }
    }

3.2. 递归遍历文件夹,计算文件夹中所有文件的大小(独立完成)

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class Demo07 {
    public static void main(String[] args) throws IOException {
        File aaaFile = new File("exceptionfile/aaa1");
        //获取数量
        long fileSize = getFileSize(aaaFile);
        System.out.println(fileSize);
    }

    /**
     * 获取目录下所有文件的长度
     *
     * @param file
     */
    public static long getFileSize(File file) {
        long size = 0;
        //判断file是不是文件
        if (file.isFile()) {
            //把文件长度累加
            size += file.length();
        } else {
            //如果不是文件
            //获取里面所有的文件对象和目录对象
            File[] listFiles = file.listFiles();
            //遍历所有对象
            for (File f : listFiles) {
                //把所有下一级文件长度累加
                size += getFileSize(f);
            }
        }
        return size;
    }
}

3.3. 统计一个文件夹中每种类型文件的个数并打印(多案例几次)

以后缀名作为类型判断依据

  • 结果输出形式:

    png 3
    avi 1
    mp4 2
    txt 6
    mp3 2
    jpg 1
    xlsx 1

  • 思路:

    用map作为计数器 后缀名作为key 它的数量作为值存储 \<String,Integer>

    每次存数量前 先获取
    Integer count = map.get("png");
    如果count为null 说明之前没有存过png 这里存数量为1
    如果count不为null 说明之前存过png 这里存数量为count+1

  • 1 判断 file是否是文件

  • 2 如果是文件 获取文件夹获取后缀

    • 2. 1把后缀名存入map, 后缀名作为key 出现的次数作为value
      1. 2先去map里根据后缀名 获取值
      1. 3 如果获取到数据 说明之前已经存储过次数,再次存入的数量要+1
      1. 4 如果没有获取到数据 说明之前没有存储过 数量存1
  • 3 如果是目录,获取目录下所有文件对象

    • 遍历所有文件传入当前方法,递归调用

代码

  • 注意 map在方法外面就定义好,传入到方法里面. 保证只有一个map对象在统计数量
package link.xiaomo.demo;

import java.io.File;
import java.util.HashMap;

public class Demo04 {
    public static void main(String[] args) {
        File file = new File("mymodule/allFiles");

        //创建一个map 用来统计数量
        HashMap<String, Integer> map = new HashMap<>();
        getTypeCount(file, map);
        System.out.println(map);
    }

    /**
     * 获取文件夹里所有文件的类型的数量 存储到map中
     *
     * @param file
     */
    public static void getTypeCount(File file, HashMap<String, Integer> map) {
        //1判断是否是文件
        if (file.isFile()) {
            //如果是文件  111.png
            //2 获取文件的类型
            //2.1获取file的文件名字
            String fileName = file.getName();
            //2.2 把名字用点切割 这块注意 写点的时候 要加两个反斜杠  因为这里是正则表达式语法
            String[] ss = fileName.split("\\.");
            //2.3获取数组里的最后一个 就是文件的后缀
            String suffix = ss[ss.length - 1];
//            System.out.println(suffix);
            //3 把后缀作为key  数量作为值存在一个map里
            //3.1 存之前先获取 这个key对应的value
            Integer count = map.get(suffix);
            //3.2 判断count是否为空
            if (count == null) {
                //3.3说明第一次 遇到这个类型 数量存1
                map.put(suffix, 1);
            } else {
                //3.4 不为空 count就是之前的数量 这里就把数量+1再存储
                map.put(suffix, count + 1);
            }
        } else {
            //4如果是文件夹  就获取这个文件夹里所有的file对象
            File[] files = file.listFiles();
            //5 遍历所有file对象
            for (File f : files) {
                //6 递归处理
                getTypeCount(f, map);
            }
        }
    }
}

小结

// File类构造方法
public File(String pathname) :通过路径名创建新的 File对象。  
public File(String parent, String child) :通过父路径和子路径创建File对象
public File(File parent, String child) :通过父路径和子路径创建File对象
// File类成员方法
public String getName()  :获取构造方法中路径的名称(末尾部分)
public String getAbsolutePath() : 获取构造方法中路径的绝对路径
public String getPath() : 获取创建对象时传入的路径
public long length()  :获取文件的大小,单位是字节
public boolean isDirectory() :是否为目录(文件夹)。
public boolean exists() :判断构造方法中传递的路径是否存在
public boolean createNewFile() :文件不存在,创建一个新的空文件。
public boolean mkdir() :创建单级文件夹
public boolean mkdirs() :即可以创建单级文件夹,又可以创建多级文件夹
public boolean delete() :删除文件和文件夹,不走回收站
public String[] list() :遍历文件夹,返回一个String数组
public File[] listFiles() :遍历文件夹,返回一个File数组
如人饮水,冷暖自知。
最后更新于 2023-08-05