一. 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);
}
}
}