用Java中的File类模拟实现对系统文件的增删改查效果

码字不易,三连支持一波吧 😃

IO操作向来是各大语言的热区,而对文件的操作也是重中之重。
那么在Java中也给我们提供了很多关于文件操作的类。今天我就用一个比较基本的File类来模拟实现对文件的增删改查效果。
这里先解释一下,何谓增删改查:

  • :创建一个文件(可以是目录,可以是文件)
  • :删除指定文件或文件夹(非空)
  • :对文件重命名,这里我加以拓展,也可以实现对文件的移动
  • :遍历并统计指定目录下(包含其子目录)指定类型文件的个数,如某目录中共包含.java文件23个,以及修改日期,几行代码文字; 列出给定目录中,所有文件类型的文件个数,以及文件类型个数,以及总类型个数和总文件个数

那么废话不多说,直接开始:

步骤定位

要实现创建文件还是比较简单的:

package day_12_13.zuoye;

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

/**
 * @author soberw
 * @Classname AddFile
 * @Description 创建文件或者目录
 * @Date 2021-12-13 18:57
 */
public class AddFile {
    public static void main(String[] args) {
        //创建目录
        File file = new File("d:/hello/abc");
        if (!file.exists()) {
            file.mkdirs();
            System.out.println("创建成功!");
        }
        //在刚创建的目录中在创建一个文件
        File file1 = new File("d:/hello/abc/hello.txt");
        try {
            file1.createNewFile();
        } catch (IOException e) {
            System.out.println("创建失败!");
        }
    }
}

在这里插入图片描述
在这里插入图片描述

删除指定文件或文件夹(非空)。
如果是空文件夹或者文件,那就比较简单,以刚才添加的文件为例,现在我想删除hello.txt,实现如下:

 if (file1.exists()) {
            file1.delete();
            System.out.println("删除成功!");
        }

在这里插入图片描述
在这里插入图片描述
这当然很简单,但delete()有个缺陷,就是只能删除空目录或者单个文件,现在我想删除的目录里面存放的有文件,还有子目录,这怎么办,这里我用了递归去实现,一层一层找,一层一层删:
例如我要删除一个aaa的文件夹,其结构如下(可以说很复杂了)。
在这里插入图片描述

代码如下(注意我此时的文件路径在E:\\HelloJava\\Java_Study_Beiyou\\aaa):

package day_12_13.zuoye;

import java.io.File;

/**
 * @author soberw
 * @Classname DeleteFile
 * @Description  删除非空目录
 * @Date 2021-12-13 11:32
 */
public class DeleteFile {
    public static void main(String[] args) {
        File file = new File("E:\\HelloJava\\Java_Study_Beiyou\\aaa");
        deleteFile(file);
    }

    public static void deleteFile(File file) {
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files != null) {
                if (files.length == 0) {
                    file.delete();
                } else {
                    for (File f : files) {
                        deleteFile(f);
                    }
                }
            }
        }
        file.delete();
    }
}

此时再我再打开:
在这里插入图片描述
已经没有aaa这个文件夹了,证明删除成功!

对文件或者文件夹重命名,这里我在以一个文件为例,其路径为:D:\hello\abc\soberw.txt
在这里插入图片描述
现在我想将他更名为sober.txt
实现如下:

package day_12_13.zuoye;

import java.io.File;

/**
 * @author soberw
 * @Classname UpdateFile
 * @Description 对文件名进行修改操作
 * @Date 2021-12-13 20:14
 */
public class UpdateFile {
    public static void main(String[] args) {
        File file = new File("D:\\hello\\abc\\soberw.txt");
        File newFile = new File("D:\\hello\\abc\\sober.txt");
        if (file.exists()) {
            file.renameTo(newFile);
        }
    }
}

在这里插入图片描述
这就实现了,其实就是用的renameTo()方法,但是如果是这样那就太简单了,其实深挖一下,renameTo()方法还有很多用途:
例如:我想将一个文件移动到另一个文件下,并重命名,我可以这样做:

public static void main(String[] args) {
        File file = new File("D:\\hello\\abc\\soberw.txt");
        File newFile = new File("D:\\hello\\abc\\sober.txt");
        if (file.exists()) {
            file.renameTo(newFile);
        }
        File moveFile = new File("D:\\aaa\\bbb\\ccc.txt");
        if(file.getParentFile().exists()){
            newFile.renameTo(moveFile);
        }
    }

在这里插入图片描述
也可以修改文件夹名称:比如我想将上面的bbb文件夹修改为abc,实现如下:

        File files = new File("D:\\aaa\\bbb");
        files.renameTo(new File("D:\\aaa\\abc"));

在这里插入图片描述
这里顺便总结一下renameTo()方法的用法:

  1. 同一路径下文件重命名【文件重命名】
  2. 第将文件从一个路径移动另一个路径下,并且移动的文件进行重命名【文件移动重命名】
  3. 修改文件夹的名称

前面三个都还比较好实现,现在就剩检索了,现在我想列出指定目录下指定格式的所有文件,并附带修改时间,每个文件行数,如何实现呢?我以.java文件为例,这里我用到了递归

package day_12_13.zuoye;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;

/**
 * @author soberw
 * @Classname CountFile
 * @Description 递归统计某目录中有多少java文件?每个Java文件中有多少行代码,总有多少行代码
 * @Date 2021-12-13 16:17
 */
public class CountFile {
    //统计个数
    public static int count = 0;
    //统计行数
    public static int lines = 0;

    public static void main(String[] args) throws IOException {
        countJavaFile(new File("E:\\HelloJava\\Java_Study_Beiyou"));
        //countJavaFile(new File("G:\\"));
        System.out.printf("共%d个java文件,共%d行代码", count, lines);
    }

    public static void countJavaFile(File file) throws IOException {
        if (file.exists()) {
            if (file.isFile() && file.getName().endsWith(".java")) {
                count++;
                //读取出来但是会报错,不稳定,不推荐
                //int line = Files.readAllLines(Path.of(file.getPath())).size();

                //稳定读取
                long line = new BufferedReader(new FileReader(file)).lines().count();
                lines += line;
                System.out.printf("%s(%s)【%tF %<tT】共%d行\n", file.getParentFile(), file.getName(), file.lastModified(), line);
            } else if (file.isDirectory() && file.list() != null) {
                for (File listFile : Objects.requireNonNull(file.listFiles())) {
                    countJavaFile(listFile);
                }
            }
        }
    }
}

运行结果(太长了,这里我就截取一部分吧):
在这里插入图片描述
现在我不想指定文件类型了,我想让程序自己列出所有的类型,并统计个数,如何实现呢?
这里我用到了Map,同样还有递归,通过自己编写的CountFileType类实现:

package day_12_13.zuoye;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author soberw
 * @Classname CountFileType
 * @Description 递归统计某目录,并列出些目录中,某文件类型的文件个数?例如:包含.java文件30个,.jpg文件78个等
 * @Date 2021-12-13 16:20
 */
public class CountFileType {
    /**
     * 声明一个Map存储文件类型及次数,key对应文件类型,value对应出现次数
     */
    private static Map<String, Integer> map = new HashMap<>();

    /**
     * @description: 列出给定目录中,某文件类型的文件个数,以及文件类型个数
     * @param str: 传入的路径
     * @return: void
     * @author: soberw
     * @time: 2021/12/13 18:16
     */
    public static void show(String str) {
        File file = new File(str);
        if (file.exists()) {
            countFileType(file);
            Set<String> keySet = map.keySet();
            System.out.println("本目录下包含有:");
            int count = 0;
            for (String s : keySet) {
                count += map.get(s);
                System.out.printf("%s文件:%d个。\n", s, map.get(s));
            }
            System.out.printf("共%d种文件类型,共%d个文件。", keySet.size(), count);
        }else {
            System.out.println("请检查路径是否合法!");
        }
    }


    /**
     * @param file 文件路径
     * @description: 递归检索目录,获取文件名后缀并存入map中,value会自增一
     * @return: void
     * @author: soberw
     * @time: 2021/12/13 18:17
     */
    private static void countFileType(File file) {
        if (file.exists()) {
            if (file.isFile() && file.getName().contains(".")) {
                String type = file.getName().substring(file.getName().lastIndexOf(".")).toLowerCase();
                if (!map.containsKey(type)) {
                    map.put(type, 1);
                } else {
                    if (map.get(type) != null) {
                        map.put(type, map.get(type) + 1);
                    }
                }
            } else if (file.isDirectory() && file.list() != null) {
                for (File listFile : Objects.requireNonNull(file.listFiles())) {
                    countFileType(listFile);
                }
            }
        }
    }
}

测试如下(通过CountFileTypeTest类测试):

package day_12_13.zuoye;


/**
 * @author soberw
 * @Classname CountFileType
 * @Description 对CountFileType的测试
 * @Date 2021-12-13 16:20
 */
public class CountFileTypeTest {
    public static void main(String[] args) {
        CountFileType.show("E:\\\\HelloJava\\\\Java_Study_Beiyou");
    }
}

结果如下:
在这里插入图片描述

posted @ 2022-02-09 19:45  soberw-  阅读(220)  评论(0编辑  收藏  举报