【JAVASE学习笔记之File类、递归】:IO系列(一)

第一章File

1.1概述

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

1.2绝对路径和相对路径

绝对路径:从盘符开始的路径,这是一个完整的路径,在系统具有唯一性。

0 比如C:/java/aaa.txt  d:/image/a.png

相对路径:相对于某个目录的路径,在系统中不具有唯一性。

〇比如:bbb.txt默认是相对当前项目根目录而言。

1.3构造方法

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

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

构造方法示例代码

//文件路径名

String pathname = "D:\\aaa.txtM;

File file1 = new File(pathname);

//文件路径名

String pathname2 = "D:\\aaa\\bbb.txt"; File file2 = new File(pathname2);

//通过父路径和子路径字符串 String parent = "d:\\aaa";

String child = "bbb.txt";

File file3 = new File(parent, child);

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

File file4 = new File(parentDir, child);

小贴士

一个File对象代表硬盘中实际存在的一个文件或者目录。

无论该路径下是否存在文件或者目录,都不影响File对象的创建。

1.4常用方法

1.4.1获取功能的方法

  • public String getAbsolutePath():返回此File的绝对路径名字符串。
  • public String getPath():将此File转换为路径名字符串。
  • public String getName():返回由此File表示的文件或目录的名称。
  • public long length():返回由此File表示的文件的长度
  • File getParentFile():返回父路径文件对象 方法演示,代码如下:
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()+"字节"); 
            System.out.println("父路径文件对象:"+f.getParentFile());
            File f2 = new File("d:/aaa");

            System.out.println("目录绝对路径:M+f2.getAbsolutePath()); 
            System.out.println("目录构造路径:"+f2.getPath());
            System.out.println("目录名称:"+f2.getName());
            System.out.println("目录长度:"+f2.length());

            }

}

输出结果:

文件绝对路径d:\aaa\bbbjava

文件构造路径d:\aaa\bbbjava

文件名称bbbjava

文件长度:636字节

父路径文件对象:d:\aaa

目录绝对路径d:\aaa

目录构造路径d:\aaa

目录名称:aaa

目录长度:4096

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

1.4.2判断功能的方法

  • public boolean exists():File表示的文件或目录是否实际存在。
  • public boolean isDirectory(): File 表示的是否为目录。
  • public boolean isFile(): File 表示的是否为文件0

方法演示,代码如下:

public class FileIs {

        public static void main(String[] args) {

            File f = new File("d:\\aaa\\bbbjava");

            File f2 = new File("d:\\aaa’’);

            //判断是否存在

            System.out.println("d:\\aaa\\bbb.java 是否存在:’+f.exists());                 
            System.out.println(’d:\\aaa 是否存在:’+f2.exists());

            //判断是文件还是目录

            System.out.println(’d:\\aaa 文件?:’+f2.isFile());

            System.out.println("d:\\aaa 目录?:’+f2.isDirectory());

            }

}

输出结果:

d:\aaa\bbb.java 是否存在:true

d:\aaa是否存在:true

d:\aaa 文件false

d:\aaa 目录true

1.4.3创建删除功能的方法

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

空文件。

  • public boolean delete():删除由此File表示的文件或目录
  • public boolean mkdir():创建由此File表示的目录0
  • public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录。

方法演示,代码如下:

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 f2= new File("newDir");

            System.out.println("是否存在:"+f2.exists());// false 
            System.out.println("是否创建:"+f2.mkdir()); // true 
            System.out.println("是否存在:"+f2.exists());// 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

            }

}

API中说明delete方法,如果此File表示目录,则目录必须为空才能删除。

1.4.4遍历目录的方法

  • public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录。
  • public File[] listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录。
public class FileFor {

        public static void main(String[] args) {

            File dir = new File(Md:\\java_codeM);

            //获取当前目录下的文件以及文件夹的名称。

            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无法进行遍历。

1.5静态成员变量

  • static String pathSeparator :与系统有关的路径分隔符

 MacLinux系统是::

 Windows系统是:;

  • static String separator :与系统有关的默认名称分隔符

 MacLinux系统是:/

 Windows系统是:\

public class FileDemo01 {

        public static void main(String[] args) throws Exception{             
            System.out.println(File.pathSeparator);

            System.out.println(File.separator);

        }

}

第二章递归

2.1概述

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

public static void test01() {

         System.out.println(Mtest01M);
         test01();

}

2.2递归累和

计算1〜num的和

分析:num的累和=num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。

实现代码:

public class DiGuiDemo {

        public static void main(String[] args) {

        //计算1~num的和,使用递归完成 int num = 5;
    
        //调用求和的方法 int sum = getSum(num);

        //输出结果

        System.out.println(sum);

        }

        /*

            通过递归算法实现.

            参数列表:int 返回值类型:int

        */
    
public static int getSum(int num) {

            /*

                num为1时,方法返回1,

                相当于是方法的出口,num总有是1的情况

            */

            if(num == 1){ return 1;

}

            /*

                num不为1时,方法返回num +(num-1)的累和 递归调用getSum方法

            */

            return num + getSum(num-1);

        }

}

代码执行图解

2.3递归求阶乘

阶乘:所有小于及等于该数的正整数的积。 n的阶乘:n! = n * (n-1) *...* 3 * 2 * 1

分析:这与累和类似,只不过换成了乘法运算,学员可以自己练习,需要注意阶乘值符合int类型的范 围。

推理得出:n! = n * (n-1)!

代码实现:

public class DiGuiDemo {

            //计算n的阶乘,使用递归完成 
            public static void main(String[] args) { 
            int n = 3;

            //调用求阶乘的方法 
            int value = getValue(n);

            //输出结果
            System.out.println("阶乘为:"+ value);

            }

            /*通过递归算法实现.

            参数列表:int 返回值类型:int

            */

public static int getValue(int n) {

            // 1的阶乘为1

            if (n == 1) { 
                return 1;

            }

            /*
    
            n不为1时,方法返回n! = n*(n-1)! 递归调用getValue方法

            */

            return n * getValue(n - 1);

        }

}

2.4递归打印多级目录

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

代码实现:

public class DiGuiDemo2 {

        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()) {

            //是文件,输出文件绝对路径

            System.out.println("文件名:"+ file.getAbsolutePath()); } else {

            //是目录,输出目录绝对路径

            System.out.println("目录:"+file.getAbsolutePath());

            //继续遍历,调用printDir,形成递归 printDir(file);

        }

    }

    }

}

第三章综合案例

3.1文件搜索

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

分析:

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

代码实现:

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);

        }

    }

    }

}

3.2文件过滤器优化

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

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

分析:

  • 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
  •  accept方法,参数为File表示当前File下所有的子文件和子目录。保留住则返回true过滤掉 则返回false保留规则:

要么是.java文件。

要么是目录,用于继续遍历。

通过过滤器的作用,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(M.javaM)||pathname.isDirectory();
            }

        });

        //循环打印

        for (File file : files) { if (file.isFile()) {

        System.out.println("文件名:"+ file.getAbsolutePath());
        } else {

            printDir2(file);

                }

        }

    }

}

3.3 Lambda 优化

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

lambda 格式: ()->{}

代码实现:

public static void printDir3(File dir) {

        // lambda的改写

        File[] files = dir.listFiles(f ->{

        return f.getName().endsWith(".java")丨丨f.isDirectory();

        });

        //循环打印

        for (File file : files) { 
            if (file.isFile()) {

                System.out.println("文件名:"+ file.getAbsolutePath()); 
            } else {

                printDir3(file);

                    }
            
        }

}

不清楚lambda表达式的老哥可以看下我的另一篇文章:【JAVASE学习笔记之Lambda表达式】

猜你喜欢

转载自blog.csdn.net/qq_32798905/article/details/81503402