欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > JavaSE——File类详解(递归查找文件)

JavaSE——File类详解(递归查找文件)

2024/10/23 15:32:58 来源:https://blog.csdn.net/Helen_1997_1997/article/details/133150054  浏览:    关键词:JavaSE——File类详解(递归查找文件)

目录

一、File类的概述

二、File的三种构造方法

三、File类常见的成员方法

(一)判断、获取

1.判断的方法 

2.获取的方法

(二)创建、删除

(三)获取并遍历

(四)所有获取并遍历的方法

四、File类操作文件与递归(重要)

(一)创建文件

(二)单个文件夹查找文件

(三)递归遍历硬盘查找文件

(四)递归删除文件夹

(五)统计文件夹总大小

(六)统计各种文件数量(重要)


一、File类的概述

        File对象表示一个路径,可以是文件的路径,也可以是文件夹的路径。这个路径可以是存在的,也可以是不存在的。

        绝对路径:带盘符的。

        相对路径:不带盘符的。

二、File的三种构造方法

public File(String pathname)

根据文件路径创建文件对象

即:把字符串表示的路径变成File对象

public File(String parent, String child)

根据父路径名字符串,和子路径名字符串创建文件对象

即:把父级路径和子级路径进行拼接

public File(File parent, String child)

根据父路径对应文件对象,和子路径名字符串创建文件对象

即:把父级路径和子级路径进行拼接

public class FileDemo1 {public static void main(String[] args) {// 1.根据字符串表示的路径,变成File对象String str = "C:\\Users\\alienware\\Desktop\\a.txt";File f1 = new File(str);System.out.println(f1);// C:\Users\alienware\Desktop\a.txt// 2.父级路径:C:\Users\alienware\Desktop//   子级路径:a.txtString parent = "C:\\Users\\alienware\\Desktop";String child = "a.txt";File f2 = new File(parent, child);System.out.println(f2);// C:\Users\alienware\Desktop\a.txt// 下面的操作不建议:因为不同的操作系统下,磁盘分隔符不同// windows:\(反斜杠)    linux和macOS:/(正斜杠)File f3 = new File(parent + "\\" + child);System.out.println(f3);// C:\Users\alienware\Desktop\a.txt// 文件拼接 建议用File.separator的方式:String directory = "documents";String subDirectory = "projects";String filename = "report.pdf";String filePath1 = directory + File.separator + subDirectory + File.separator + filename;// 或者String filePath2 = "documents" + File.separator + "documents" + File.separator + "report.pdf";File file1 = new File(filePath1);File file2 = new File(filePath2);// file.getAbsolutePath():返回调用该方法时File对象所表示的文件或目录的绝对路径System.out.println(file1.getAbsolutePath());System.out.println(file2.getAbsolutePath());// G:\develop\workspace\one\basecode\documents\projects\report.pdf// 3.把一个File表示的路径和String表示路径进行拼接File parent2 = new File("C:\\Users\\alienware\\Desktop");String child2 = "a.txt";File f4 = new File(parent2, child2);System.out.println(f4);// C:\Users\alienware\Desktop\a.txt}
}

三、File类常见的成员方法

(一)判断、获取

1.判断的方法 

public class FileDemo2 {public static void main(String[] args) {// 1.对一个文件的路径进行判断File f1 = new File("D:\\test\\a.txt");System.out.println(f1.isDirectory()); // falseSystem.out.println(f1.isFile()); // trueSystem.out.println(f1.exists()); // trueSystem.out.println("----------------------------");// 2.对一个文件夹进行判断File f2 = new File("D:\\test\\bbb");System.out.println(f2.isDirectory()); // trueSystem.out.println(f2.isFile()); // falseSystem.out.println(f2.exists()); // trueSystem.out.println("----------------------------");// 3.对一个不存在的路径进行判断File f3 = new File("D:\\test\\ddd");System.out.println(f3.isDirectory()); // falseSystem.out.println(f3.isFile()); // falseSystem.out.println(f3.exists()); // false}
}

2.获取的方法

public class FileDemo3 {public static void main(String[] args) {     // 1.length  返回文件的大小(字节数量)// 细节1:这个方法只能获取文件的大小,单位是字节// 如果单位想要M,G,可以不断的除以1024// 细节2:这个方法无法获取[文件夹]的大小// 如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在一起。File f1 = new File("D:\\test\\a.txt");long len = f1.length();System.out.println(len); // 970File f2 = new File("D:\\test\\bbb");long len2 = f2.length();System.out.println(len2); // 0System.out.println("--------------------------------");// 2.getAbsolutePath 返回文件的绝对路径File f3 = new File("D:\\test\\a.txt");String path1 = f3.getAbsolutePath();System.out.println(path1);// D:\test\a.txtFile f4 = new File("chapter16\\a.txt");String path2 = f4.getAbsolutePath();System.out.println(path2);// G:\develop\workspace\one\basecode\chapter16\a.txtSystem.out.println("--------------------------------");// 3.getPath 返回定义文件时使用的路径// 即:new File()中是什么就返回什么File f5 = new File("D:\\test\\a.txt");String path3 = f5.getPath();System.out.println(path3);// D:\test\a.txtFile f6 = new File("chapter16\\a.txt");String path4 = f6.getPath();System.out.println(path4);// chapter16\a.txtSystem.out.println("--------------------------------");// 4.getName 返回文件的名称,带后缀// 如果是文件,就返回文件名+后缀名// 如果是文件夹,就返回文件夹的名字File f7 = new File("D:\\test\\a.txt");String name1 = f7.getName();System.out.println(name1);// a.txt  文件名+后缀名File f8 = new File("D:\\test\\bbb");String name2 = f8.getName();System.out.println(name2);// bbbSystem.out.println("--------------------------------");// 5.lastModified 返回文件的最后修改时间(时间毫秒值)File f9 = new File("D:\\test\\a.txt");long lastModified = f9.lastModified();System.out.println(lastModified);// 1729183893084   毫秒值SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String format = simpleDateFormat.format(lastModified);System.out.println(format);// 2024-10-18 00:51:33}
}

(二)创建、删除

注意:delete方法默认只能删除文件和空文件夹,直接删除不走回收站

public class FileDemo4 {public static void main(String[] args) throws IOException {// 1.createNewFile 创建一个新的空的文件// 细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true//       如果当前路径表示的文件是存在的,则创建失败,方法返回false// 细节2:如果父级路径是不存在的,那么方法会有异常IOException// 细节3:createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件File file = new File("D:\\test\\aaa\\c.txt");boolean newFile = file.createNewFile();System.out.println(newFile); // 2.mkdir   make Directory,文件夹(目录)// 细节1:windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false// 细节2:mkdir方法只能创建单级文件夹,无法创建多级文件夹。File file2 = new File("D:\\test\\aaa");boolean mkdir = file2.mkdir();System.out.println(mkdir);// 3.mkdirs   创建多级文件夹// 细节:既可以创建单级的,又可以创建多级的文件夹File file3 = new File("D:\\test\\aaa\\bbb\\ccc");File file3 = new File("D:\\test\\ggg");boolean mkdirs = file3.mkdirs();System.out.println(mkdirs);/*4.delete    删除文件、文件夹细节:如果删除的是文件,则直接删除,不走回收站。如果删除的是空文件夹,则直接删除,不走回收站如果删除的是有内容的文件夹,则删除失败*/// 1.创建File对象File f1 = new File("D:\\test\\aaa");// 2.删除boolean b = f1.delete();System.out.println(b);}
}

(三)获取并遍历

public File[] listFiles()        获取当前该路径下所有内容

  1. 当调用者File表示的路径不存在时,返回NullPointerException
  2. 当调用者File表示的路径是文件时,返回NullPointerException
  3. 当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
  4. 当调用者File表示的路径是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
  5. 当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
  6. 当调用者File表示的路径是需要权限才能访问的文件夹时,返回NullPointerException
public class FileDemo6 {public static void main(String[] args) {// 1.创建File对象File f = new File("D:\\test");// 2.listFiles方法//作用:获取aaa文件夹里面的所有内容,把所有的内容放到数组中返回File[] files1 = f.listFiles();for (File file : files1) {// file依次表示test文件夹里面的每一个文件或者文件夹System.out.println(file);}}
}

运行结果: 

(四)所有获取并遍历的方法

public class FileDemo7 {public static void main(String[] args) {// 1.listRoots  获取系统中所有的盘符File[] arr = File.listRoots();System.out.println(Arrays.toString(arr));// [C:\, D:\, E:\, G:\]// 2.list()    获取当前该路径下所有内容(仅仅能获取名字)File file = new File("D:\\test");String[] arr2 = file.list();System.out.println(Arrays.toString(arr2));// [a.avi, aaa, b.txt, bbb, c.txt, ccc, fff]// 3.list(FilenameFilter filter)  利用文件名过滤器获取当前该路径下所有内容// 需求:获取D:\\test文件夹里面所有的txt文件File file1 = new File("D:\\test");// accept方法的形参,依次表示test文件夹里面每一个文件或者文件夹的路径// 参数一:父级路径; 参数二:子级路径// 返回值:如果返回值为true,就表示当前路径保留//        如果返回值为false,就表示当前路径舍弃不要String[] arr3 = file1.list(new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {File file2 = new File(dir, name);return file2.isFile() && name.endsWith(".txt");}});System.out.println(Arrays.toString(arr3));// [b.txt, c.txt]// lambda表达式String[] arr4 = file1.list((s1, s2) -> {File file2 = new File(s1, s2);return file2.isFile() && s2.endsWith(".txt");});System.out.println(Arrays.toString(arr4));// [b.txt, c.txt]}
}
public class FileDemo8 {public static void main(String[] args) {// 1.创建File对象File f = new File("D:\\test");// 2.需求:打印里面所有的txt文件File[] files = f.listFiles();for (File file : files) {if (file.isFile() && file.getName().endsWith(".txt")) {System.out.println(file);}}/*** D:\test\b.txt* D:\test\c.txt*/}
}
public class FileDemo9 {public static void main(String[] args) {// 创建File对象File f = new File("D:\\test");// 调用listFiles(FileFilter filter)File[] arr = f.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {return pathname.isFile() && pathname.getName().endsWith(".txt");}});System.out.println(Arrays.toString(arr));// [D:\test\b.txt, D:\test\c.txt]// lambda表达式File[] arr2 = f.listFiles((name) -> name.isFile() && name.getName().endsWith(".txt"));System.out.println(Arrays.toString(arr2));// [D:\test\b.txt, D:\test\c.txt]File[] arr3 = f.listFiles(new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {File file = new File(dir, name);return file.isFile() && name.endsWith(".txt");}});System.out.println(Arrays.toString(arr3));// [D:\test\b.txt, D:\test\c.txt]}
}

四、File类操作文件与递归(重要)

(一)创建文件

public class TestDemo1 {public static void main(String[] args) throws IOException {File file = new File("chapter16\\aaa");// mkdirs()方法无论文件夹在不在,都会创建成功file.mkdirs();File file1 = new File(file + File.separator + "a.txt");// createNewFile()方法如果文件已存在是falseboolean newFile = file1.createNewFile();if (newFile) {System.out.println("创建成功");} else {System.out.println("创建失败");}}
}

(二)单个文件夹查找文件

        需求:定义一个方法,查找某一个文件夹中,是否有以.avi结尾的文件,暂时不需要考虑子文件夹。

public class TestDemo2 {public static void main(String[] args) {boolean b = haveAVI(new File("D:\\test"));System.out.println(b);// D:\test\a - 副本.avi// true}private static boolean haveAVI(File src) {File[] files = src.listFiles();for (File f : files) {if (f.isFile() && f.getName().endsWith(".avi")) {System.out.println(f);return true;}}return false;}
}

(三)递归遍历硬盘查找文件

凡是考虑到文件夹里面的递归操作,可套用下面的步骤:

  1. 进入文件夹src

  2. 遍历数组,依次得到src里面的每一个文件或文件夹

  3. 判断:如果是文件,就可以执行题目的业务逻辑

  4. 判断:如果是文件夹,就可以递归      (细节:再次调用本方法的时候,参数一定要是src的次一级路径)

public class TestDemo3 {public static void main(String[] args) {// 查找电脑中所有以.avi结尾的文件findAvi();}private static void findAvi() {File[] files = File.listRoots();for (File file : files) {findAvi(file);}}private static void findAvi(File src) {// 1.进入文件夹srcFile[] files = src.listFiles();// 2.遍历数组,依次得到src里面的每一个文件或文件夹if (files != null) {for (File file : files) {if (file.isFile()){// 3.判断:如果是文件,就可以执行题目的业务逻辑String name = file.getName();if (name.endsWith(".avi")){System.out.println(name);}//  4.判断:如果是文件夹,就可以递归//  (细节:再次调用本方法的时候,参数一定要是src的次一级路径)}else {findAvi(file);}}}}
}

运行结果:

 

(四)递归删除文件夹

递归删除ggg文件夹

删除一个多级文件夹
如果我们要删除一个有内容的文件夹:1.先删除文件夹里面所有的内容;2.再删除自己

public class TestDemo4 {public static void main(String[] args) {// 删除一个多级文件夹delete(new File("D:\\test\\ggg"));}private static void delete(File src) {// 进入srcFile[] files = src.listFiles();// 如果执行过程中遇到了空指针异常,可以对files做非空判断if (files != null) {// 遍历数组for (File file : files) {if (file.isFile()) {// 判断,如果是文件,就删除file.delete();} else {// 判断,如果是文件夹,就递归// 这里的参数一定是src的次一级路径delete(file);}}// 最后删除自己src.delete();}}
}

ggg文件夹被成功删除! 

(五)统计文件夹总大小

public class TestDemo5 {public static void main(String[] args) {long len = getLen(new File("D:\\test")) / 1024;System.out.println(len + "KB");// 178KB}private static long getLen(File src) {// 1.定义变量进行累加long len = 0;// 2.进入src文件夹File[] files = src.listFiles();// 3.遍历数组if (files != null) {for (File file : files) {// 4.判断是不是文件if (file.isFile()) {// 5.是文件,则进行长度累加len += file.length();} else {// 6.不是文件,则继续遍历len += getLen(file);}}}// 7.返回最后累加的长度return len;}
}

(六)统计各种文件数量(重要)

需求:统计一个文件夹中每种文件的个数并打印。(考虑子文件夹)
打印格式如下:
txt:3个
doc:4个
jpg:6个

参数:
      要统计的那个文件夹
返回值:
      用来统计map集合
      键:后缀名 值:次数

      a.txt
      a.a.txt
      aaa(不需要统计的)

遍历方式一:

public class Test6 {public static void main(String[] args) throws IOException {File file = new File("D:\\test");HashMap<String, Integer> hm = getCount(file);System.out.println(hm);// {jpg=6, txt=3, avi=3, doc=4}}public static HashMap<String, Integer> getCount(File src) {// 1.定义集合用来统计HashMap<String, Integer> hm = new HashMap<>();// 2.进入src文件夹File[] files = src.listFiles();// 3.遍历数组for (File file : files) {// 4.判断,如果是文件,统计if (file.isFile()) {// a.txtString name = file.getName();String[] arr = name.split("\\.");if (arr.length >= 2) {String endName = arr[arr.length - 1];if (hm.containsKey(endName)) {// 存在int count = hm.get(endName);count++;hm.put(endName, count);} else {// 不存在,没有后缀名的文件,分割后长度为1hm.put(endName, 1);}}} else {// 5.判断,如果是文件夹,递归// sonMap里面是子文件中每一种文件的个数HashMap<String, Integer> sonMap = getCount(file);// hm:  txt=1  jpg=2  doc=3// sonMap: txt=3 jpg=1// 遍历sonMap把里面的值累加到hm当中Set<Map.Entry<String, Integer>> entries = sonMap.entrySet();for (Map.Entry<String, Integer> entry : entries) {String key = entry.getKey();int value = entry.getValue();if (hm.containsKey(key)) {// 存在int count = hm.get(key);count = count + value;hm.put(key, count);} else {// 不存在hm.put(key, value);}}}}return hm;}
}

遍历方式二:

public class TestDemo6 {public static void main(String[] args) {HashMap<String, Integer> hashMap = getCount(new File("D:\\test"));System.out.println(hashMap);// {jpg=6, txt=3, avi=3, doc=4}}private static HashMap<String, Integer> getCount(File src) {File[] files = src.listFiles();HashMap<String, Integer> hm = new HashMap<>();for (File file : files) {if (file.isFile()) {String name = file.getName();String[] split = name.split("\\.");// 分成2个才考虑if (split.length >= 2) {String endName = split[split.length - 1];if (hm.containsKey(endName)) {// 存在int count = hm.get(endName);count++;hm.put(endName, count);} else {// 不存在hm.put(endName, 1);}}} else {HashMap<String, Integer> sonMap = getCount(file);Set<String> keySet = sonMap.keySet();for (String key : keySet) {int value = sonMap.get(key);if (hm.containsKey(key)) {// 存在int count = hm.get(key);count = count + value;hm.put(key, count);} else {// 不存在hm.put(key, value);}}}}return hm;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com