File类、方法递归-CSDN博客

85 阅读8分钟

一. File类概述

 在计算机中,有没有一块硬件可以永久存储数据的?

  • 磁盘中数据的形式就是文件,文件时数据的载体。
  • 硬盘也可以叫做磁盘,文件夹就是目录。

File类概述

  • File类的对象代表操作系统的文件(文件和文件夹(目录)),File类在java.io.File包下。
  • File类提供了存储:创建文件对象代表文件,获取文件信息(大小、修改时间)、删除文件、创建文件(文件夹)等功能。
  • File类不能读写文件内容!
  • IO流技术可以对硬盘中的文件进行读写。

 二. File类的使用以及File类常用API

2.1 创建File对象

  •  相对路径:一般定位模块中的文件,相对到工程下。
package com.gch.d1file;

import java.io.File;

/**
   目标:学会创建File对象定位操作系统的文件(文件  文件夹)
 */
public class FileDemo1 {
    public static void main(String[] args) {
        // 1、创建File对象(制定了文件的路径)
        // 路径写法:C:\\Users\\A.G.H\\Pictures\\高春晖.jpg
        //         C:/Users/A.G.H/Pictures/高春晖.jpg
//        File f = new File("C:\\Users\\A.G.H\\Pictures\\高春晖.jpg");
        File f = new File("C:/Users/A.G.H/Pictures/高春晖.jpg");
        long size = f.length(); // 是文件的字节大小
        System.out.println(size); // 31377

        // 2.File创建对象,支持绝对路径,也支持相对路径(重点)
        File f1 = new File("C:\\Users\\A.G.H\\Pictures\\飞书20230309-194620.jpg"); // 绝对路径
        System.out.println(f1.length()); // 是文件的字节大小

        // 相对路径:一般定位模块中的文件。相对到工程下
        File f2 = new File("day09-file-io-app/src/data.txt");
        // 是文件的字节大小
        System.out.println(f2.length()); // 6

        // 3.File创建对象,可以是文件也可以是文件夹
        File f3 = new File("C:\\Users");
        System.out.println(f3.exists()); // 判断这个路径是否存在,这个文件夹是否存在
    }
}

2.2 File类常用API

常用API/方法:判断文件类型、获取文件信息

package com.gch.d1file;
import java.io.File;
import java.text.SimpleDateFormat;

/**
     目标:File类的获取功能的API
     - public String getAbsolutePath()  :返回此File的绝对路径名字符串。
     - public String getPath()  : 获取创建文件对象的时候用的路径
     - public String getName()  : 返回由此File表示的文件或目录的名称。
     - public long length()  :    返回由此File表示的文件的长度。
 */
public class FileDemo02 {
    public static void main(String[] args) {
        // 1.绝对路径创建一个文件对象
        File f1 = new File("C:/Users/A.G.H/Pictures/高春晖.jpg");
        // a.获取它的绝对路径。
        System.out.println(f1.getAbsolutePath()); // C:\Users\A.G.H\Pictures\高春晖.jpg
        // b.获取文件定义的时候使用的路径。
        System.out.println(f1.getPath()); // C:\Users\A.G.H\Pictures\高春晖.jpg
        // c.获取文件的名称:带后缀。
        System.out.println(f1.getName()); // 高春晖.jpg
        // d.获取文件的大小:字节个数。
        System.out.println(f1.length()); // 31377
        // e.获取文件的最后修改时间
        long time = f1.lastModified(); // 时间毫秒值  // 最后修改时间:2022/11/20 22:59:31
        System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time));
        // f、判断文件是文件还是文件夹
        System.out.println(f1.isFile()); // true
        System.out.println(f1.isDirectory()); // false

        System.out.println("--------------------------------------------------------------------");

        File f2 = new File("day09-file-io-app\\src\\data.txt");
        // a.获取它的绝对路径。
        System.out.println(f2.getAbsolutePath()); // C:\code\javasepromax\javasepromax\day09-file-io-app\src\data.txt
        // b.获取文件定义的时候使用的路径。
        System.out.println(f2.getPath()); // day09-file-io-app\src\data.txt
        // c.获取文件的名称:带后缀。
        System.out.println(f2.getName()); // data.txt
        // d.获取文件的大小:字节个数。
        System.out.println(f2.length()); // 字节大小 6
        // e.获取文件的最后修改时间
        long time1 = f2.lastModified();  // 最后修改时间:2023/03/18 18:39:21
        System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time1));
        // f、判断文件是文件还是文件夹
        System.out.println(f2.isFile()); // true
        System.out.println(f2.isDirectory()); // false
        System.out.println(f2.exists()); // true

        File file = new File("C:/");
        System.out.println(file.isFile()); // false
        System.out.println(file.isDirectory()); // true
        System.out.println(file.exists()); // true

        File file1 = new File("C:/aaa");
        System.out.println(file1.isFile()); // false
        System.out.println(file1.isDirectory()); // false
        System.out.println(file1.exists()); // false
    }
}

常用方法:创建文件、删除文件功能

package com.gch.d1file;

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

/**
     目标:File类的创建和删除的方法
     - public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,
              创建一个新的空文件。 (几乎不用的,因为以后文件都是自动创建的!)
     - public boolean delete() :删除由此File表示的文件或目录。 (只能删除空目录)
     - public boolean mkdir() :创建由此File表示的目录。(只能创建一级目录)
     - public boolean mkdirs() :可以创建多级目录(建议使用的)
 */
public class FileDemo03 {
    public static void main(String[] args) throws IOException {
        File f = new File("day09-file-io-app\\src\\data.txt");
        // a.创建新文件,创建成功返回true ,反之 ,不需要这个,以后文件写出去的时候都会自动创建
        System.out.println(f.createNewFile()); // false
        File f1 = new File("day09-file-io-app\\src\\data02.txt");
        System.out.println(f1.createNewFile()); // true(几乎不用的,因为以后文件都是自动创建的!)

        // b.mkdir创建一级目录
        File f2 = new File("D:/resources/aaa");
        System.out.println(f2.mkdir());

        // c.mkdirs创建多级目录(重点)
        File f3 = new File("D:/resources/ccc/ddd/eee/ffff");
//        System.out.println(f3.mkdir());
        System.out.println(f3.mkdirs()); // 支持多级创建

        // d.删除文件或者空文件夹
        System.out.println(f1.delete());
        File f4 = new File("D:/resources/xueshan.jpeg");
        System.out.println(f4.delete()); // 占用一样可以删除

        // 只能删除空文件夹,不能删除非空文件夹.
        File f5 = new File("D:/resources/aaa");
        System.out.println(f5.delete());
    }
}

常用方法:遍历文件夹

package com.gch.d1file;

import java.io.File;
import java.util.Arrays;

/**

    目标:File针对目录的遍历
    - public String[] list():
         获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
    - public File[] listFiles()(常用):
         获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
 */
public class FileDemo04 {
    public static void main(String[] args) {
        // 1、定位一个目录
        File f1 = new File("C:/resources");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }

        // 2.一级文件对象
        // 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
        File[] files = f1.listFiles();
        for (File f : files) {
            System.out.println(f.getAbsolutePath());
        }

        // 注意事项
        File dir = new File("C:/resources/ddd");
        File[] files1 = dir.listFiles();
        System.out.println(Arrays.toString(files1));
    }
}

 三. 方法递归

3.1 方法递归的形式

package com.gch.d2_recursion;

/**
   递归的形式:方法自己调自己
 */
public class RecursionDemo1 {
    public static void main(String[] args) {
        test(); // StackOverflowError:栈内存溢出
        test2(); //  StackOverflowError:栈内存溢出
    }
    public static void test(){
        System.out.println("========test被执行=======");
        test(); // 方法递归 直接递归形式
    }
    public static void test2(){
        System.out.println("========test2被执行=======");
        test3(); // 方法递归 间接递归形式
    }
    public static void test3(){
        System.out.println("========test3被执行=======");
        test2(); // 方法递归 间接递归形式
    }
}

3.2 方法递归的应用、执行流程、递归算法的三个核心要素

package com.gch.d2_recursion;

/**
   目标:递归的算法和执行流程
 */
public class RecursionDemo2 {
    public static void main(String[] args) {
        System.out.println(f(5)); // 120

    }
    public static int f(int n){
        if(n == 1){
            return 1;
        }else{
            return f(n - 1) * n;
        }
    }
}

 递归算法的三要素大体可以总结为:

  • 递归的公式:f(n) = f(n - 1) * n;
  • 递归的终结点:f(1)
  • 递归方向:递归的方向必须走向终结点!

 

3.3 方法递归的经典案例

package com.gch.d2_recursion;

/**
   目标:1-n求和
 */
public class RecursionDemo3 {
    public static void main(String[] args) {
        System.out.println("1-100的和是:" + f(100)); // 1-100的和是:5050
    }
    public static int f(int n){
        if(n == 1){
            return 1;
        }else{
            return f(n - 1) + n;
        }
    }
}

package com.gch.d2_recursion;

/**
   目标:猴子吃桃
   公式(数学科学性):f(x) - f(x)/2 -1 = f(x+1)
                 2f(x) - f(x) - 2 = 2f(x+1)
                 f(x) - 2 = 2f(x+1)
                 f(x) = 2(f(x+1) + 1)
 */
public class RecursionDemo4 {
    public static void main(String[] args) {
        System.out.println(f(1));
    }
    public static int f(int n){
        if(n == 10){ // 终结点
            return 1;
        }else{
            return 2 * (f(n + 1) + 1);
        }
    }
}

3.4 非规律化的方法递归案例

package com.gch.d2_recursion;

import java.io.File;

public class RecursionDemo5 {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        // 2.传入目录和文件名称
        searchFile(new File("C:/"),"android.lock");
        long endTime = System.currentTimeMillis();
        System.out.println("耗时:" + (endTime - startTime) / 1000 + "s");
    }

    /**
     * 1.搜索某个目录下的全部文件,找到我们想要的文件
     * @param dir 被搜索的源目录/文件夹
     * @param fileName 被搜索的文件名称
     */
    public static void searchFile(File dir,String fileName){
        // 3.判断dir是否为目录
        if(dir != null && dir.isDirectory()){
            // 可以找了
            // 4.提取当前目录下的一级文件对象
            File[] files = dir.listFiles(); // null []
            // 5.判断是否存在一级文件对象,存在才可以遍历
            if(files != null && files.length > 0){
                for (File file : files) {
                    // 6.判断当前遍历的一级文件对象是文件 还是 目录
                    if(file.isFile()){
                        // 7.是不是咱们要找的,是把路径输出即可
                        if(file.getName().contains(fileName)){
                            System.out.println("找到了:" + file.getAbsolutePath());
                            return;
                        }
                    }else{
                        // 8.是文件夹,继续递归寻找
                        searchFile(file,fileName);
                    }
                }
            }
        }else{
            System.out.println("对不起,当前搜索的位置不是文件夹!");
        }
    }

}

 

package com.gch.d2_recursion;

/**
   目标:啤酒2元1瓶,4个盖子可以换1瓶,2个空瓶可以换一瓶
        请问10元钱可以喝多少啤酒,剩余多少空瓶和盖子。
        答案:15瓶   3瓶盖   1空瓶子
 */
public class RecursionDemo6 {
    // 定义一个静态成员变量用于控制可以买的酒的数量
    public static int totalNumber; // 记录可以买酒的总数量
    public static int lastBottleNumber; // 记录每次剩余的空瓶子数量
    public static int lastBottleCap; // 记录每次剩余的盖子个数
    public static void main(String[] args) {
        // 1.拿钱买酒
        buy(10);
        System.out.println("总共可以买" + totalNumber + "瓶酒喝!");
        System.out.println("剩余" + lastBottleNumber + "个空瓶子,和" + lastBottleCap + "个盖子");
    }
    public static void buy(int money){
        // 2.看可以立马买多少瓶
        int buyNumber = money / 2;
        totalNumber += buyNumber;

        // 3.把盖子  和瓶子 换算成钱
        // 统计本轮总的盖子数  和  瓶子数
        int bottleNumber = lastBottleNumber + buyNumber;
        int bottleCap = lastBottleCap + buyNumber;

        // 4.统计可以换算的钱
        int allMoney = 0;

        // 把瓶子数换成钱
        if(bottleNumber >= 2){
            allMoney += (bottleNumber / 2) * 2;
        }
        // 换成钱之后剩余的瓶子个数
        lastBottleNumber = (bottleNumber) % 2;

        // 把盖子数换成钱
        if(bottleCap >= 4){
            allMoney += (bottleCap / 4) * 2;
        }
        // 换成钱后剩余的盖子数
        lastBottleCap = (bottleCap) % 4;

        // 5.换成钱之后继续买酒
        if(allMoney >= 2){
            buy(allMoney);
        }
    }
}