Java的File学习总结(含递归)

1、File类

  java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。简单来说,Java把计算机中文件和文件夹(目录)封装为File类,我们可以使用File类对文件和文件夹进行操作。而且File类是一个与系统无关的类,即任何的操作系统都可以使用这个类中的方法。

1.1、构造方法

常用的构造方法:

方法描述
public File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
public File(String parent, String child)从父路径名字符串和子路径名字符串创建新的File实例
public File(File parent, String child)从父抽象路径名和子路径名字符串创建新的File实例
public File(URI uri)通过将给定的uri转换为一个抽象路径名来创建线的File实例
        /* public File(String pathname):文件路径名
            路径可以是文件结尾,也可以是文件夹结尾。
            路径可以是相对路径,也可以是绝对路径。
            路径可以存在,也可以是不存在。
            创建File对象,只是把字符串路径封装为File对象,不会考虑路径真假的情况
         */
        File file1 = new File("D:\\demo");
        System.out.println(file1); // D:\demo
        File file2 = new File("D:\\demo\\aaa.txt");
        System.out.println(file2); // D:\demo\aaa.txt
        File file3 = new File("aaa.txt");
        System.out.println(file3); // aaa.txt

        /* public File(String parent, String child):把路径分成了父路径与子路径两部分
            两个路径可单独书写,使用灵活
         */
        File file4 = new File("D:\\", "demo\\aaa.txt");
        System.out.println(file4); // D:\demo\aaa.txt

        /* public File(File parent, String child):把路径分成了父路径与子路径两部分,且父路径为File类型
            父路径是File类型,可以使用File类方法对路径进行操作
         */
        File parent = new File("D:\\");
        File file5 = new File(parent, "demo\\aaa.txt");
        System.out.println(file5); // D:\demo\aaa.txt

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

1.2、常用方法

1.2.1、获取功能的方法

方法描述
public String getAbsolutePath()返回此File的绝对路径名字符串
public String getPath()将此File转换为路径名字符串
public String getName()返回由此File表示的文件或目录的名称
public long length()返回由此File表示的文件的长度
import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File file1 = new File("D:\\IdeaProjects\\TestDemo\\user.jpg");  // 此路径文件均存在
        File file2 = new File("user.jpg");
        File file3 = new File("user");

        /** public String getAbsolutePath():返回此File的绝对路径名字符串
         *  获取构造器方法中传递的路径。
         *  无论是绝对路径还是相对路径,返回的都是绝对路径。
         */
        System.out.println("file1.getAbsolutePath():" + file1.getAbsolutePath());
        System.out.println("file2.getAbsolutePath():" + file2.getAbsolutePath());

        /** public String getPath():将此File转换为路径名字符串
         *  获取构造器方法中传递的路径,构造器方法中的路径是什么就返回什么。
         *  File类中的toString()方法就是调用的getPath()方法。
         */
        System.out.println("file1.getPath():" + file1.getPath());
        System.out.println("file2.getPath():" + file2.getPath());
        System.out.println("file2.toString():" + file2.toString());

        /** public String getName():返回由此File表示的文件或目录的名称
         *  获取构造方法中传递路径(可以是绝对路径,也可以是相对路径)的结尾部分(文件/文件夹)。
         *  File类中的toString()方法就是调用的getPath()方法。
         */
        System.out.println("file1.getName():" + file1.getName());
        System.out.println("file2.getName():" + file2.getName());
        System.out.println("file3.getName():" + file3.getName());

        /** public long length():返回由此File表示的文件的长度
         *  获取构造方法中路径所指定的文件大小,以字节为单位。
         *  文件夹是没有大小概念的
         *  若路径不存在,则返回值为0
         */
        System.out.println("file1.length():" + file1.length());
        System.out.println("file2.length():" + file2.length());
        System.out.println("file3.length():" + file3.length()); 
    }
}

运行结果:
file1.getAbsolutePath():D:\IdeaProjects\TestDemo\user.jpg
file2.getAbsolutePath():D:\IdeaProjects\TestDemo\user.jpg
file1.getPath():D:\IdeaProjects\TestDemo\user.jpg
file2.getPath():user.jpg
file2.toString():user.jpg
file1.getName():user.jpg
file2.getName():user.jpg
file3.getName():user
file1.length()21896
file2.length()21896
file3.length()0

  Tips: API中说明length()方法表示文件的长度。但是File对象表示目录,则返回值未指定。

1.2.2、判断功能的方法

方法描述
public boolean exists()此File表示的文件或目录是否实际存在
public boolean isDirectory()此File表示的是否为目录
public boolean isFile()此File表示的是否为文件
import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File file1 = new File("D:\\IdeaProjects\\TestDemo\\user.jpg"); // 此路径文件均存在
        File file2 = new File("D:\\IdeaProjects\\TestDemo");
        File file3 = new File("D:\\IdeaProjects\\TestDemo2\\user2.jpg"); // 此路径文件不存在

        // 判断是否存在
        System.out.println(file1.exists()); // true
        System.out.println(file2.exists()); // true
        System.out.println(file3.exists()); // false

        // 判断是文件还是目录
        System.out.println(file1.isDirectory()); // false
        System.out.println(file1.isFile()); // true
        System.out.println(file2.isDirectory()); // true
        System.out.println(file2.isFile()); // false
        System.out.println(file3.isDirectory()); // false
        System.out.println(file3.isFile()); // false
    }
}

1.2.3、增删功能的方法

方法描述
public boolean createNewFile()当且仅当具有该名称的文件尚不存在时,创建一个新的空文件
public boolean delete()删除由此File表示的文件或目录
public boolean mkdir()创建由此File表示的目录
public boolean mkdirs()创建由此File表示的目录,包括任何必需但不存在的父目录
import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        File file1 = new File("D:\\IdeaProjects\\TestDemo\\a.txt"); // 此文件不存在,路径存在
        File file2 = new File("D:\\IdeaProjects\\test"); // 此文件夹不存在,路径存在

        /** public boolean createNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件
         *  若文件不存在则创建文件,返回true
         *  若文件存在,则不会创建文件,返回false
         *  注意,此方法只能创建文件,不能创建文件夹。且创建文件的路径必须存在,否则会抛出异常
         */
        System.out.println(file1.createNewFile()); // true
        // 再次创建此文件,文件已存在,无法创建
        System.out.println(file1.createNewFile()); // false

        /** public boolean mkdir():创建由此File表示的目录,不能创建文件!
         *  只能创建单级文件夹
         *  若文件夹不存在则创建文件夹,返回true
         *  若文件夹存在或路径不存在,则不会创建文件夹,返回false
         */
        System.out.println(file2.mkdir()); // true
        // 再次创建此文件夹,文件夹已存在,无法创建
        System.out.println(file2.mkdir()); // false
        // 不可创建多级文件夹
        File file3 = new File("D:\\IdeaProjects\\test\\aa\\bb\\cc");
        System.out.println(file3.mkdir()); // false

        /** public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录
         *  可以创建单级或多级文件夹
         */
        // 创建多级目录,D:\\IdeaProjects\\test\\aa\\bb\\cc
        System.out.println(file3.mkdirs()); // true

        /** public boolean delete():删除由此File表示的文件或文件夹
         *  文件或文件夹删除成功,返回true
         *  若删除文件夹,且文件夹中有内容,则不会删除,返回false
         *  若路径不存在,返回false
         */
        // D:\\IdeaProjects\\test路径存在,且test目录下存在内容
        System.out.println(file2.delete()); // false
        // 删除D:\\IdeaProjects\\test\\aa\\bb\\cc
        System.out.println(file3.delete()); // true
        // 再次删除D:\\IdeaProjects\\test\\aa\\bb\\cc,不存在此文件夹
        System.out.println(file3.delete()); // false
    }
}

1.3、文件目录的遍历

方法描述
public String[] list()返回一个String数组,表示该File目录中的所有子文件或目录
public File[] listFiles()返回一个File数组,表示该File目录中的所有的子文件或目录
public boolean mkdir()创建由此File表示的目录
public boolean mkdirs()创建由此File表示的目录,包括任何必需但不存在的父目录

在这里插入图片描述

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

public class FileDemo {
    public static void main(String[] args) throws IOException {
    	// 路径不存在包NullPointerException异常
        File dir = new File("D:\\IdeaProjects\\TestDemo"); // 此路径存在
        // 获取当前目录下的文件以及文件夹名称(包括隐藏的文件或文件夹)
        String[] names = dir.list();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("-----------");
        // 获取当前目录下的文件以及文件夹对象(包括隐藏的文件或文件夹)
        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

运行结果:
.idea
a.txt
out
src
TestDemo.iml
user.jpg
-----------
D:\IdeaProjects\TestDemo\.idea
D:\IdeaProjects\TestDemo\a.txt
D:\IdeaProjects\TestDemo\out
D:\IdeaProjects\TestDemo\src
D:\IdeaProjects\TestDemo\TestDemo.iml
D:\IdeaProjects\TestDemo\user.jpg

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

2、递归

2.1、基本概述

递归: 指在当前方法内调用自己的这种现象。

递归的分类: 递归分为两种,直接递归和间接递归。
  直接递归称为方法自身调用自己。
  间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。

递归的使用前提: 当调用方法时,方法的主体不变,但每次调用方法的参数不同。

注意事项:
  (1)递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
  (2)在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
  (3)构造方法,禁止递归!

2.2、递归的使用

2.2.1、求阶乘

阶乘: 所有小于及等于概数的正整数的积。

n的阶乘:n!= n * (n-1) * ... * 3 * 2 * 1

代码实现:

public class RecursionDemo {
    public static void main(String[] args) {
        int num = 5;
        System.out.println("5的阶乘为:" + getValue(num));
    }

    private static int getValue(int n) {
        if (n == 1) {
            return 1; //当num为1时,停止递归
        }
        return n * getValue(n - 1);
    }
}
运行结果:
5的阶乘为:120

2.2.2、打印多级目录

分析: 多级目录的打印,就是当目录的嵌套。遍历之前,无从知道到底有多少级目录,所以我们还是要使用递归实现。

代码实现:

import java.io.File;

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

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

3、文件搜索案例

3.1、案例分析

需求: 所搜某一目录中所有的.java文件。

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

代码实现:

import java.io.File;

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

    private static void printDir(File dir) {
        // 获取子文件和目录
        File[] files = dir.listFiles();
        for (File file : files) {
            // 判断是文件,输出文件绝对路径
            if (file.isFile()) {
                // 判断是否为.java文件
                if (file.getName().endsWith(".java")){
                    System.out.println("文件名:" + file.getAbsolutePath());
                }
            } else {
                // 是目录,继续遍历,递归
                printDir(file);
            }
        }
    }
}
运行结果:
文件名:D:\IdeaProjects\TestDemo\src\com\atlantis\file\FileDemo.java
文件名:D:\IdeaProjects\TestDemo\src\com\atlantis\file\RecursionDemo.java

3.2、文件过滤器优化

  java.io.FileFilter是一个接口,是File的过滤器。 该接口的对象可以传递给File类的 listFiles(FileFilter)作为参数, 接口中只有一个方法。

//测试pathname是否应该包含在当前File目录中,符合则返回true。
boolean accept(File pathname); 

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

代码实现:

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

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

    private static void printDir(File dir) {
        // 匿名内部类方式,创建过滤器子类对象
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".java") || pathname.isDirectory();
            }
        });
        // 循环打印
        for (File file : files) {
            if (file.isFile()) {
                System.out.println("文件名:" + file.getAbsolutePath());
            } else {
                printDir(file);
            }
        }
    }
}

运行结果:
文件名:D:\IdeaProjects\TestDemo\src\com\atlantis\file\FileDemo.java
文件名:D:\IdeaProjects\TestDemo\src\com\atlantis\file\RecursionDemo.java

3.3、Lambda优化

分析: FileFilter是只有一个方法的接口,因此可以用lambda表达式简写。

代码实现:

    private static void printDir(File dir) {
        // 匿名内部类方式,创建过滤器子类对象
        File[] files = dir.listFiles(file -> {
            return file.getName().endsWith(".java") || file.isDirectory();
        });
        // 循环打印
        for (File file : files) {
            if (file.isFile()) {
                System.out.println("文件名:" + file.getAbsolutePath());
            } else {
                printDir(file);
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值