A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 Java-yao 于 2018-11-26 15:36 编辑

[就业班 2018.11.21] File类 递归笔记

1. File类
java.io.File类
"文件"和"目录"的路径名的抽象表现形式, 主要用于文件和目录的创建, 查找和删除等操作

File类的静态成员变量
// 静态成员变量
static String pathSeparator: // 路径分隔符的字符串形式
static char pathSeparatorChar: // 路径分隔符的char形式
Windows系统是 分号;
Linux系统是 冒号:
static String separator: // 文件名称分隔符的字符串形式
static char separatorChar: // 文件名称分隔符的char形式
Window系统是 反斜杠\
Linux系统是 正斜杠/

绝对路径和相对路径
绝对路径:
以盘符开始的路径         
如: "D:\\a\\hi.txt"
相对路径:
不以盘符开始的简化路径. IDEA项目, 相对于项目的根目录
        如: "a\\1.mp3", "123.txt"
        "d:\\t"
注意事项:
1. 路径不区分大小写 (在Windows系统中不区分大小写, Linux, Mac区分)
2. 路径一般写成字符串, 而字符串中一个\是转义, 所以要写两个\\

File类: 构造方法
构造方法(创建了File对象, 并将其指向该路径. 不会真正在磁盘上创建这个文件
File File(String pathname): 根据 路径字符串 封装一个File对象
File File(String parent, String child): 根据 父路径字符串 和 子路径字符串 封装File对象
File File(File parent, String child): 根据 父路径的File对象 和 子路径 封装File对象

测试File类的构造方法代码:创建File对象后, 并不会在磁盘上创建文件或目录!
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        File f1 = new File("z:\\z.txt");  // 不存在的路径也可以创建File对象
        System.out.println(f1);

        File f2 = new File("目录\\", "a.txt");  // 相对路径也可以
        System.out.println(f2);

        File f3 = new File(new File("d:\\"), "c.txt");
        System.out.println(f3);
    }
}


File类: 获取方法
String getAbsolutePath(): 返回此File的绝对路径名字符串
String getPath(): 获取File对象的封装路径 (创建对象时传入的路径)
String getName(): 获取File对象的文件名或目录名  d:\a\b\c\aaa.txt
long length(): 获取File表示的"文件"大小的字节byte数 (不能获取目录的大小)

测试File类的获取方法代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        // String getAbsolutePath(): 返回此File的绝对路径名字符串
        File f1 = new File("d:\\a.txt");  // 测试使用绝对路径
        String f1AbsolutePath = f1.getAbsolutePath();
        System.out.println(f1AbsolutePath);  // d:\a.txt

        File f2 = new File("a.txt");  // 测试使用相对路径, 只是将项目的路径拼接到当前相对路径之前, 并不检测路径是否真实
        String f2AbsolutePath = f2.getAbsolutePath();
        System.out.println(f2AbsolutePath);  // D:\itheima-teach\sjz-javaee-11\s2-进阶\advance-code\a.txt

        // String getPath(): 获取File对象的封装路径 (创建对象时传入的路径)
        File f3 = new File("d:\\a.txt");  // 测试使用绝对路径
        String f3Path = f3.getPath();
        System.out.println(f3Path);  // d:\a.txt

        File f4 = new File("a.txt");  // 测试使用相对路径
        String f4Path = f4.getPath();
        System.out.println(f4Path);  // a.txt

        // String getName(): 获取File对象的文件名或目录名
        File f5 = new File("d:\\a\\b\\c\\a.txt");
        String f5Name = f5.getName();
        System.out.println(f5Name);  // a.txt

        File f6 = new File("d:\\a\\b\\c");
        String f6Name = f6.getName();
        System.out.println(f6Name);  // c

        // long length(): 获取File表示的文件大小的字节数 (不能获取目录的大小)
        File f7 = new File("day08\\src\\com\\itheima\\test01\\Test.java");   // 存在的文件
        System.out.println(f7.length());   // 2407
        File f8 = new File("z:\\a.txt");   // 不存在的文件
        System.out.println(f8.length());   // 0
        File f9 = new File("day08");       // 存在的目录
        System.out.println(f9.length());   // 0
        File f10 = new File("z:\\aaa");    // 不存在的目录
        System.out.println(f10.length());  // 0

    }
}

File类: 判断方法
boolean exists(): 判断File对象代表的文件或目录是否实际存在
boolean isDirectory(): 判断File表示的是否为目录
boolean isFile(): 判断File表示的是否为文件

测试File类的判断方法代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        // boolean exists(): 判断File对象代表的文件或目录是否实际存在
        File f1 = new File("day08");  // 传入存在的路径
        System.out.println(f1.exists());  // true

        File f2 = new File("d:\\a.txt");  // 传入不存在的路径
        System.out.println(f2.exists());  // false

        // boolean isDirectory(): 判断File表示的是否为目录
        File f3 = new File("day08");  // 存在的目录
        System.out.println(f3.isDirectory()); // true

        File f4 = new File("day08\\src\\com\\itheima\\test01\\Test.java");  // 存在的文件
        System.out.println(f4.isDirectory());  // false

        File f5 = new File("sdfdfdsaf");  // 不存在的目录
        System.out.println(f5.isDirectory());  // false

        // boolean isFile(): 判断File表示的是否为文件
        File f6 = new File("day08\\src\\com\\itheima\\test01\\Test.java");  // 存在的文件
        System.out.println(f6.isFile()); // true

        File f7 = new File("day08");  // 存在的目录
        System.out.println(f7.isFile());  // false

        File f8 = new File("sdfdfdsaf.txt");  // 不存在的文件
        System.out.println(f8.isFile());  // false
    }
}


File类: 创建删除方法

boolean createNewFile(): 当文件不存在时, 创建一个新的空文件
        false: 路径已经存在(无论文件还是目录)
抛IO异常: 写的路径不符合逻辑 (Y:\\a.txt\dsfsd)
boolean delete(): 删除由此File表示的文件或目录.
        删除目录时: 必须是空目录
boolean mkdir(): 创建File表示的目录  "d:\\a\\b\\c\\我的目录"
        false: 1. 路径已经存在(无论文件还是目录)   2. 写的路径不符合逻辑 (Y:\\a.txt\dsfsd)
boolean mkdirs(): 创建File表示的多级目录   "d:\\a\\b\\c\\我的目录"
        false: 1. 路径已经存在(无论文件还是目录)   2. 写的路径不符合逻辑 (Y:\\a.txt\ds)

测试File类的创建删除方法代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 在当前的模块中, 创建a目录(注意用相对路径时加上模块名)
        File aDir = new File("day08\\a");
        boolean b1 = aDir.mkdir();
        System.out.println("在当前的模块中, 创建a目录:" + b1);

        // 在a目录中创建b目录
        File bDir = new File("day08\\a\\b");
        boolean b2 = bDir.mkdirs();
        System.out.println("在a目录中创建b目录:" + b2);

        // 在b目录中创建b.txt文件和c.txt文件
        File bFile = new File("day08\\a\\b\\b.txt");
        boolean b3 = bFile.createNewFile();
        System.out.println("在b目录中创建b.txt文件:" + b3);

        File cFile = new File("day08\\a\\b\\c.txt");
        boolean b4 = cFile.createNewFile();
        System.out.println("在b目录中创建c.txt文件:" + b4);

        // 删除c.txt文件
        boolean b5 = cFile.delete();
        System.out.println("删除c.txt文件:" + b5);
    }
}


File类: 遍历目录方法
String[] list(): 获取当前File目录下的所有子文件或目录的名字数组
File[] listFiles(): 获取当前File目录中的所有子文件或目录的File对象数组

注意:
        只能用表示目录的File对象调用
        用文件的File对象, 或者路径不存在, 调用会报错

测试遍历目录方法的代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        // 创建File对象, 指向当前模块
        File dir = new File("day08");

        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
        /*
            day08\a
            day08\day08.iml
            day08\src
         */
    }
}


3. 递归
Java中实现递归的方式: 方法内部调用方法自己 (所以必须定义方法)

递归的分类:
        直接递归: 方法自己调用方法
        间接递归: A方法调用B方法, B方法调用C方法, C方法调用A方法

递归时的注意事项:
1. 限定条件(出口), 保证递归能够停止(就是在某种情况下方法不再调用自己), 否则会栈内存溢出
2. 递归次数不能太多, 否则会栈内存溢出
3. 构造方法不能递归

递归的使用前提:
调用方法时, 方法的主体不变, 但每次传递的参数值不同, 可以使用递归

递归实现思路
        将要解决的问题, 封装为方法
                求1~n的和: 定义方法
[Java] 纯文本查看 复制代码
                private static int getSum(int n) {  // 解决问题: 求n~1的和
                        // 出口(方法自己不再调用自己)
                        if (n == 1) {
                return 1;
                        }
                        // n~1的和 = n + ((n-1)~1的和)
            return n + getSum(n-1);
                }

        在方法内部, 拆解问题, 不能解决的小问题, 继续递归调用方法
递归遍历多级目录

boolean endsWith(String suffix): 判断字符串是否以指定的字符串结尾
判断文件后缀: boolean b = "aaa.JAVA".endsWith(".java");
String toLowerCase(): 将字符串转为小写字母
String s = "aaa.JAVA".toLowerCase();
s: "aaa.java"

递归思想分析:
大问题:
打印aaa目录下的"所有"java文件路径 = 判断java文件打印 + (打印bbb目录下的"所有"java文件路径)?
打印bbb目录下的"所有"java文件路径 = 判断java文件打印 + (打印ccc目录下的"所有"java文件路径)?
打印ccc目录下的"所有"java文件路径 = 判断java文件打印

要解决的问题(定义的方法): 打印 参数 目录下的"所有"java文件路径
代码实现:
出口: 没有子目录
共性的公式:  判断java文件打印 + 递归调用方法(打印ccc目录下的"所有"java文件路径)?

代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        File dir = new File("day08");
        printJavaFile(dir);
    }

    // 定义方法打印某个目录中的java文件
    public static void printJavaFile(File dir) {
        // 先获取当前目录中的所有子文件和子目录
        File[] childFiles = dir.listFiles();
        for (File childFile : childFiles) {
            if(childFile.isFile()) {
                // 是子文件, 则判断文件名是否是.java结尾
                if (childFile.getName().toLowerCase().endsWith(".java")) {
                    System.out.println(childFile);
                }
            } else {
                // 是子目录, 则递归调用, 查看子目录中的java文件
                printJavaFile(childFile);
            }
        }
    }
}


FileFilter文件过滤器的原理和使用
java.io.File类: Filter过滤器
File[] listFiles(FileFilter filter): 返回文件过滤器过滤后的File对象数组
File[] listFiles(FilenameFilter filter): 返回文件过滤器过滤后的File对象数组

java.io.FileFilter接口: 用于File对象的过滤器
boolean accept(File pathName):
true则会将参数的File对象加入返回的File[], false则不加入

java.io.FilenameFilter接口: 将File对象拆分为父路径和子路径来判断的过滤器
boolean accept(File dir, String name):
true则将参数的File对象加入返回的File[], false则不加入
dir: 被找到的文件所在的目录 (父路径)
name: 文件的名称          (子路径)

示例代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) {
        File dir = new File("day08");
        printJavaFile(dir);
    }

    public static void printJavaFile(File dir) {
        // 获取当前目录下的子文件和子文件夹, 传入过滤器对象

        // 匿名内部类方式
        /*File[] childFiles = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isDirectory() || name.toLowerCase().endsWith(".java");
            }
        });*/

        // Lambda标准格式
        /*File[] childFiles = dir.listFiles((File d, String name) -> {
            return new File(d, name).isDirectory() || name.toLowerCase().endsWith(".java");
        });*/

        // Lambda省略格式
        File[] childFiles = dir.listFiles((d, name) -> new File(d, name).isDirectory() || name.toLowerCase().endsWith(".java"));


        // 现在数组中只有.java文件和子目录
        for (File childFile : childFiles) {
            if (childFile.isFile()) {
                // 如果是文件, 那肯定是.java文件, 直接打印即可
                System.out.println(childFile);
            } else {
                // 如果是目录, 仍然是递归调用
                printJavaFile(childFile);
            }
        }
    }
}





1 个回复

倒序浏览
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马