File类

  • 能够说出File对象的创建方式
  • 能够说出File类获取名称的方法名称
  • 能够说出File类获取绝对路径的方法名称
  • 能够说出File类获取文件大小的方法名称
  • 能够说出File类判断是否是文件的方法名称
  • 能够说出File类判断是否是文件夹的方法名称
  • 能够辨别相对路径和绝对路径
  • 能够遍历文件夹
  • 能够解释递归的含义
  • 能够使用递归的方式计算5的阶乘
  • 能够说出使用递归会内存溢出隐患的原因

概述

在这里插入图片描述

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法。

1. 静态成员变量

  • static String pathSeparator:与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
  • static char pathSeparatorChar:与系统有关的路径分隔符。
  • static String separator: 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
  • static char separatorChar :与系统有关的默认名称分隔符。
import java.io.File;

public class Demo01File {
    public static void main(String[] args) {
       
        String pathSeparator = File.pathSeparator;
        System.out.println(pathSeparator); // 路径分隔符 windows:分号;  linux:冒号:
        System.out.println(File.pathSeparatorChar);

        String separator = File.separator;
        System.out.println(separator); // 文件名称分隔符 windows:反斜杠\  linux:正斜杠/
        System.out.println(File.separatorChar);
    }
}

结果:

;
;
\
\

注意

  1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

操作路径

  • 路径不能写死了
C:\develop\a\a.txt  windows
C:/develop/a/a.txt  linux "C:"+File.separator+"develop"+File.separator+"a"+File.separator+"a.txt"

2. 构造方法

第一种

  • 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
public File(String pathname);

参数:字符串的路径名称

路径要求

  1. 路径可以是以文件结尾,也可以是以文件夹结尾
  2. 路径可以是相对路径,也可以是绝对路径
  3. 路径可以是存在,也可以是不存在
  4. 创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况

举例:

// 文件路径名
String pathname = "D:\\aaa.txt";
File file1 = new File(pathname); 

// 文件路径名
String pathname2 = "D:\\aaa\\bbb.txt";
File file2 = new File(pathname2); 

第二种

  • 父路径名字符串和子路径名字符串创建新的 File实例。
public File(String parent, String child);

参数

把路径分成了两部分

  1. String parent:父路径
  2. String child:子路径

好处

父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化

举例:

// 通过父路径和子路径字符串
 String parent = "d:\\aaa";
 String child = "bbb.txt";
 File file3 = new File(parent, child);

第三种

  • 父抽象路径名和子路径名字符串创建新的 File实例。
public File(File parent, String child);

参数

把路径分成了两部分

  1. File parent:父路径

  2. String child:子路径

好处

  1. 父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化

  2. 父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象

举例:

// 通过父级File对象和子路径字符串
File parentDir = new File("d:\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child);

3. 常用方法

在这里插入图片描述

获取方法

绝对路径
  • 返回此File的绝对路径名字符串

    获取的构造方法中传递的路径,无论路径是绝对的还是相对的,getAbsolutePath方法返回的都是绝对路径

public String getAbsolutePath();
相对路径
  • 将此File转换为路径名字符串。
 public String getPath();
绝对路径和相对路径
  • 绝对路径:从盘符开始的路径,这是一个完整的路径。如:`` c:\111\a.txt`
  • 相对路径:相对于项目目录的路径,这是一个便捷的路径。如:c:\\111
注意
  1. 路径是不区分大小写
  2. 路径中的文件名称分隔符windows使用反斜杠
  3. 反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

代码:

public class FilePath {
    public static void main(String[] args) {
      	// D盘下的bbb.java文件
        File f = new File("D:\\bbb.java");
        System.out.println(f.getAbsolutePath());
      	
		// 项目下的bbb.java文件
        File f2 = new File("bbb.java");
        System.out.println(f2.getAbsolutePath());
    }
}

结果:

D:\bbb.java
D:\idea_project_test4\bbb.java
文件/目录名
  • 返回由此File表示的文件或目录的名称。

    获取的就是构造方法传递路径的结尾部分(文件/文件夹)

public String getName();
文件长度
  • 返回由此File表示的文件的长度。

    获取的是构造方法指定的文件的大小,以字节为单位,length()表示文件的长度。

    如果File对象表示目录,则返回值未指定。

public long length();
注意
  1. 文件夹是没有大小概念的,不能获取文件夹的大小(length方法返回值不一定是0)
  2. 如果构造方法中给出的路径不存在,那么length方法返回0

代码如下:

public class FileGet {
    public static void main(String[] args) {
        File f = new File("d:/aaa/bbb.java");     
        System.out.println("文件绝对路径:"+f.getAbsolutePath());
        System.out.println("文件构造路径:"+f.getPath());
        System.out.println("文件名称:"+f.getName());
        System.out.println("文件长度:"+f.length()+"字节");

        File f2 = new File("d:/aaa");     
        System.out.println("目录绝对路径:"+f2.getAbsolutePath());
        System.out.println("目录构造路径:"+f2.getPath());
        System.out.println("目录名称:"+f2.getName());
        System.out.println("目录长度:"+f2.length());
    }
}

length(),表示文件的长度。如果File对象表示目录,则返回值未指定。

结果:

文件绝对路径:d:\aaa\bbb.java
文件构造路径:d:\aaa\bbb.java
文件名称:bbb.java
文件长度:636字节

目录绝对路径:d:\aaa
目录构造路径:d:\aaa
目录名称:aaa
目录长度:4096

判断功能的方法

  • 此File表示的文件或目录是否实际存在(常用于判断构造方法中的路径是否存在)
public boolean exists();
  • 此File表示的是否为目录
public boolean isDirectory();
  • 此File表示的是否为文件
public boolean isFile();

代码如下:

public class FileIs {
    public static void main(String[] args) {
        File f = new File("d:\\aaa\\bbb.java");
        File f2 = new File("d:\\aaa");
        
      	//不存在,就没有必要获取
        if(f1.exists()){
            System.out.println(f1.isDirectory());
            System.out.println(f1.isFile());
        }
        
        if(f2.exists()){
            System.out.println(f2.isDirectory());
            System.out.println(f2.isFile());
        }
    }
}

创建删除的方法

创建文件、目录的路径和名称在构造方法中给出(构造方法的参数)

创建文件
  • 当且仅当具有该名称的文件不存在时,创建一个新的空文件。
public boolean createNewFile();

注意

  • 此方法只能创建文件,不能创建文件夹

  • 创建文件的路径必须存在,否则会抛出异常IOException

创建目录
  • public boolean mkdir() :创建目录。
  • public boolean mkdirs()创建多级目录,包括任何必需但不存在的父目录。

返回值:布尔值

  • true:文件夹不存在,创建文件夹
  • false:
    • 文件夹存在,不会创建;
    • 构造方法中给出的路径不存在也返回false ;

注意

  • 此方法只能创建文件夹,不能创建文件
删除文件/目录
  • 删除由此File表示的文件或目录。

    如果此File表示目录,则目录必须为空才能删除

public boolean delete();

代码如下:

public class FileCreateDelete {
    public static void main(String[] args) throws IOException {
        // 文件的创建
        File f = new File("aaa.txt");
        System.out.println("是否存在:"+f.exists()); // false
        System.out.println("是否创建:"+f.createNewFile()); // true
        System.out.println("是否存在:"+f.exists()); // true
        // 注意!!!
        File f3 = new File("E:\pic\\新建文件夹3");
        boolean b3 = f3.createNewFile();
        System.out.println(b3); // true  要看类型,不要被名字忽悠!
		
     	// 目录的创建
      	File f2= new File("newDir");	
        System.out.println("是否存在:"+f2.exists());// false
        System.out.println("是否创建:"+f2.mkdir());	// true
        System.out.println("是否存在:"+f2.exists());// true
        // 注意!!!
        File f2 = new File("E:\\pic\\aaa.txt");
        boolean b2 = f1.mkdir();
        System.out.println(b2); // true  创建的是目录,不要被名字忽悠!

		// 创建多级目录
      	File f3= new File("newDira\\newDirb");
        System.out.println(f3.mkdir());// false
        File f4= new File("newDira\\newDirb");
        System.out.println(f4.mkdirs());// true
      
      	// 文件的删除
       	System.out.println(f.delete());// true
      
      	// 目录的删除
        System.out.println(f2.delete());// true
        System.out.println(f4.delete());// false
    }
}

4. 目录的遍历

第一种

  • 获取该File目录中的所有【子文件或目录,包括隐藏文件和文件夹】
public String[] list();
原理
  1. 遍历构造方法中给出的目录,获取目录中所有文件/文件夹的名称
  2. 把获取到的多个名称存储到一个String类型的数组中

第二种

  • 获取该File目录中的所有的【子文件或目录,包括隐藏文件和文件夹】
public File[] listFiles();
原理
  1. 遍历构造方法中给出的目录,获取目录中所有的文件/文件夹,把文件/文件夹封装为File对象
  2. 把获取到的多个File对象存储到File数组中。

注意

  1. list方法和listFiles方法遍历的是构造方法中给出的目录
  2. 如果构造方法中给出的目录的路径不存在,会抛出空指针异常
  3. 如果构造方法中给出的路径不是一个目录,也会抛出空指针异常

代码:

public class FileFor {
    public static void main(String[] args) {
        File dir = new File("d:\\java_code");
      
      	//获取当前目录下的文件以及文件夹的名称。
		String[] names = dir.list();
		for(String name : names){
			System.out.println(name);
		}
        //获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。

结果:

[Ljava.lang.String;@50cbc42f
1.txt
111
43.jpg
aaa
我是一个文件夹.txt
我是一个隐藏文件.txt
我是一个隐藏文件夹
新建文件夹
新建文件夹3
=======================
[Ljava.io.File;@75412c2f
E:\pic\1.txt
E:\pic\111
E:\pic\43.jpg
E:\pic\aaa
E:\pic\我是一个文件夹.txt
E:\pic\我是一个隐藏文件.txt
E:\pic\我是一个隐藏文件夹
E:\pic\新建文件夹
E:\pic\新建文件夹3

5. 文件操作

文件搜索

搜索D:\aaa 目录中的.java 文件。

分析

  1. 目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录。
  2. 遍历目录时,获取的子文件,通过文件名称,判断是否符合条件。

代码实现

public class DiGuiDemo3 {
    public static void main(String[] args) {
        // 创建File对象
        File dir  = new File("D:\\aaa");
      	// 调用打印目录方法
        printDir(dir);
    }

    public static void printDir(File dir) {
      	// 获取子文件和目录
        File[] files = dir.listFiles();
      	
      	// 循环打印
        for (File file : files) {
            if (file.isFile()) {
              	// 是文件,判断文件名并输出文件绝对路径
                if (file.getName().endsWith(".java")) {
                    System.out.println("文件名:" + file.getAbsolutePath());
                }
            } else {
                // 是目录,继续遍历,形成递归
                printDir(file);
            }
        }
    }
}

文件过滤器优化

在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器。

第一种重载方法

File[] listFiles(FileFilter filter);
参数

java.io.FileFilter是一个接口,用来过滤文件(File对象)。

其内部只有一个用来过滤文件的方法:

  • 保留返回true,过滤返回false
boolean accept(File pathname);
原理

listFiles方法进行了如下操作

  1. 遍历构造方法中给出的目录,获取目录中所有的文件/文件夹,把文件/文件夹封装为File对象
  2. 调用参数传递过滤器的accept方法
  3. 把获取到的多个File对象,传递到accept方法的参数。

格式:

File dir = new File("E:\\a");
File[] files = dir.listFiles(new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        //过滤规则:pathname是文件夹,返回true
        return pathname.isDirectory();
    }
});

案例:遍历某路径下全部.txt文件

分析;

  1. 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
  2. accept方法,参数为File,表示当前File下所有的子文件和子目录。保留住则返回true,过滤掉则返回false。保留规则:要么是.java文件。要么是目录,用于继续遍历。
  3. 通过过滤器的作用listFiles(FileFilter)返回的数组元素中,子文件对象都是符合条件的,可直接打印。

代码实现:

public class DiGuiDemo4 {
    public static void main(String[] args) {
        File dir = new File("D:\\aaa");
        printDir2(dir);
    }
  
    public static void printDir2(File dir) {
      	// 创建过滤器子类对象【匿名内部类方式】
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".java")||pathname.isDirectory();
            }
        });
        
        // 【lambda的改写】
    	File[] files = dir.listFiles(f ->{ 
      		return f.getName().endsWith(".java") || f.isDirectory(); 
    	});
    	// 【简化lambda写法】
    	File[] files = dir.listFiles((pathname)->
                pathname.isDirectory() 
             || pathname.getName().toLowerCase().endsWith(".txt")
        );
        
      	// 循环打印
        for (File file : files) {
            if (file.isFile()) {
                System.out.println("文件名:" + file.getAbsolutePath());
            } else {
                // 【递归】
                printDir2(file);
            }
        }
    }
}      

第二种重载方法

java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名。

用于过滤文件名:

File[] listFiles(FilenameFilter filter);

其内部的抽象方法:

  • 用来过滤文件的方法测试指定文件是否应该包含在某一文件列表中。
boolean accept(File dir, String name);

参数

  • File dir:构造方法中传递的被遍历的目录

  • String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称

代码实现:

package cn.luis.demo03.Filter;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

public class Demo02Filter {
    public static void main(String[] args) {
        File file = new File("E:\\pic");
        getAllFile(file);
    }

    /*
        定义一个方法,参数传递File类型的目录
        方法中对目录进行遍历
     */
    // 匿名内部类方式
    public static void getAllFile(File dir){ // 传递过滤器对象
        File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                // File(dir,name):封装为一个File(文件)对象,组合成完整路径
                return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".txt");
            }
        });

        //分析:FilenameFilter是只有一个【方法】的接口,因此可以用lambda表达式简写。
        //使用Lambda表达式优化匿名内部类(接口中只有一个抽象方法)
        File[] files = dir.listFiles((File d, String name)-> {
            return new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt");
        });

        // 简化lambda表达式
        File[] files = dir.listFiles((d, name)->
            new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt")
        );

        for (File f : files) {
            //对遍历得到的File对象f进行判断,判断是否是文件夹
            if(f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可:递归(自己调用自己)
                getAllFile(f); // 递归
            }else{
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}

结果:

E:\pic\1.txt
E:\pic\我是一个隐藏文件.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值