异常、file、综合案例
一、异常
1.什么是异常
异常:就是代表程序出现的问题
误区:不是让我们以后不出先异常,而是程序出了一场之后我们该如何人取处理
(1)Error
代表的系统级别错误,属于严重问题,系统一旦出现问题,sun公司会把这些错误封装成Error对象,Error是给sun公司自己用的,不是给我们程序员的,因此开发人员不用管他
(2)异常Exception
Exception:叫做异常,代表程序可能出现的问题,我们通常会用Exception以及他的子类来哦封装程序出现的问题
①RuntimeException:
RuntimeException本身以及子类在运行时期就会出现错误提示,编译阶段不会出现异常提醒。运行时出现异常,一般都是由于参数传递错误带来的问题,例如:数组索引越界异常
②其他异常:
编译阶段就会出现的异常,例如日期解析异常,没有继承于RuntimeException的异常,直接继承于Exception,编译阶段就会有错误提示
2.异常在代码中的作用
(1)一场是用来查询bug的关键参考信息
public class ExcrptionTest01 {
public static void main(String[] args) {
/* 异常的作用
(1)一场是用来查询bug的关键参考信息
(2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况*/
Student [] arr = new Student[3];
String name = arr[0].getName();
System.out.println(name);
//报错信息
NullPointerException: //空指针异常
Cannot invoke "com_07Gather_jinjie._04Exception.Student.getName()"//不能执行这个方法
because "arr[0]" is null //因为 arr[0] 是空值
at com_07Gather_jinjie._04Exception.ExcrptionTest01.main(ExcrptionTest01.java:10)//具体代码出现错误的位置,在com_07Gather_jinjie._04Exception包里面的ExcrptionTest01类里面的main方法的第10行
}
}
public class ExceptionTest02 {
public static void main(String[] args) {
/* 异常的作用
(1)一场是用来查询bug的关键参考信息
(2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况*/
Student2 stu = new Student2("张三,23");
System.out.println(stu);
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 1 out of bounds for length 1 //索引越界异常,1索引超出了数组长度1
at com_07Gather_jinjie._04Exception.Student2.<init>(Student2.java:15)
at com_07Gather_jinjie._04Exception.ExceptionTest02.main(ExceptionTest02.java:9)
}
}
(2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况
package com_07Gather_jinjie._04Exception;
public class ExceptionTest03 {
public static void main(String[] args) {
/*
异常作用一:异常是用来查询bug的关键参考信息
异常作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况
*/
//1.创建学生对象
Student s1 = new Student();
//年龄:(同学) 18~40岁
s1.setAge(88);//就知道了50赋值失败
//选择1:自己悄悄处理
//选择2:打印在控制台上
//构造方法里对年龄做出限制
/* public void setAge(int age) {
if (age > 50 || age < 18) {
System.out.println("年龄赋值失败");
throw new RuntimeException();
} else {
this.age = age;
}
}*/
/*年龄赋值失败
Exception in thread "main" java.lang.RuntimeException
at com_07Gather_jinjie._04Exception.Student.setAge(Student.java:50)
at com_07Gather_jinjie._04Exception.ExceptionTest03.main(ExceptionTest03.java:14)*/
}
}
3.异常的处理方式
(1)JVM虚拟机默认的处理方式
🔺把异常的名称,异常原因及异常出现的位置等信息输出在了控制台上
🔺遇到异常,程序会停止执行,下面的代码也不会执行了
public class ExceptionTest04 {
public static void main(String[] args) {
System.out.println("狂踹瘸子那条好腿");
System.out.println(2/0);//算术异常 ArithmeticException
System.out.println("是秃子终会发光");
System.out.println("火鸡味锅巴");
/*
狂踹瘸子那条好腿
Exception in thread "main" java.lang.ArithmeticException: / by zero
atcom_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest04.main(ExceptionTest04.java:13)*/
//抛出异常后,下面的代码不会执行
}
}
(2)自己处理(捕获异常)
①格式
try{
可能出现异常的代码;
} catch(异常类名 变量名){
异常的处理代码;
}
②目的:
当代码出现异常时,不会停止虚拟机,可以让程序继续往下执行
public class ExceptionTest05 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
try{
//可能出现异常的代码;
System.out.println(arr[10]);//此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
//new ArrayIndexOutOfBoundsException();
//拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象
//如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码
//当catch里面所有的代码执行完毕,继续执行try...catch体系下面的其他代码
}catch(ArrayIndexOutOfBoundsException e){
//如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
System.out.println("索引越界了");
}
System.out.println("看看我执行了吗?");
}
}
③可能遇到的为问题
🔺如果try模块中没有遇到问题,代码怎么执行
如果try中没有遇到问题,会把try里面所有的代码全部执行完毕,不会执行catch里面的代码
注意:只有当出现了异常才会执行catch里面的代码
public class ExceptionTest06 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
try{
System.out.println(arr[0]);//1
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("索引越界了");
}
System.out.println("看看我执行了吗?");//看看我执行了吗?
}
}
//控制台输出
1
看看我执行了吗?
🔺如果try中可能会遇到多个问题,怎么执行
如果try中可能会遇到多个问题,会写多个catch与之对应
细节: 如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
了解性:
在JDK7之后,我们可以在catch中同时捕获多个异常,中间用|进行隔开
表示如果出现了A异常或者B异常的话,采取同一种处理方案
public class ExceptionTest07 {
public static void main(String[] args) {
//JDK7
int[] arr = {1, 2, 3, 4, 5, 6};
try{
System.out.println(arr[10]);//ArrayIndexOutOfBoundsException
System.out.println(2/0);//ArithmeticException
String s = null;
System.out.println(s.equals("abc"));
}catch(ArrayIndexOutOfBoundsException | ArithmeticException e){
System.out.println("索引越界了");
}catch(NullPointerException e){
System.out.println("空指针异常");
}catch (Exception e){
System.out.println("Exception");
}
System.out.println("看看我执行了吗?");
}
}
//控制台输出
索引越界了
看看我执行了吗?
🔺如果try中遇到的问题没有被捕获,怎么执行
自己处理(捕获异常)灵魂三问:
如果try中遇到的问题没有被捕获,相当于try…catch的代码白写了,最终还是会交给虚拟机进行处理
public class ExceptionTest08 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
try{
System.out.println(arr[10]);//new ArrayIndexOutOfBoundsException();
}catch(NullPointerException e){
System.out.println("空指针异常");
}
System.out.println("看看我执行了吗?");
}
}
//控制台输出
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6
at com_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest08.main(ExceptionTest08.java:16)
🔺如果try中遇到了问题,那么try模块中下面的其他代码还会执行吗
自己处理(捕获异常)灵魂四问:
如果try中遇到了问题,那么try下面的其他代码还会执行吗?
下面的代码就不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体
但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理
public class ExceptionTest09 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
try{
System.out.println(arr[10]);
System.out.println("看看我执行了吗?... try");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("索引越界了");
}
//try会拿到第一个遇见的异常对象,去往catch寻找,不会再回到try了,因此try中第一个异常下面的其他异常不会生效
System.out.println("看看我执行了吗?... 其他代码");
}
}
//控制台输出
索引越界了
看看我执行了吗?... 其他代码
④异常中的常见方法
★Throwable的成员方法
方法名称 | 说明 |
---|---|
public String getMessage() | 返回次throwable的详细消息字符串 |
public String toString() | 返回此可抛出的简短描述 |
public voidprintStackTrace() | 把异常的错误信息输出在控制台 |
public class ExceptionTest10 {
public static void main(String[] args) {
int []arr = {1,2,3,4,5};
try {
System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
String message = e.getMessage();
System.out.println(message);
/*Index 10 out of bounds for length 5
看看我执行了吗*/
String str = e.toString();
System.out.println(str);
/*java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
看看我执行了吗*/
e.printStackTrace();不会停止虚拟机
/*java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
at com_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest10.main(ExceptionTest10.java:14)
看看我执行了吗*/
}
System.out.println("看看我执行了吗");
}
}
★为什么printStackTrace方法会以红色的字体打印在控制台呢
在底层是利用System.err.println进行输出,把异常的错误信息以红色字体输出在控制台上
细节:仅仅是打印信息,不会停止程序运行
(3)抛出异常
①throws
注意:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常
public void 方法()throws 异常类名1,异常类名2 . . . {
. . .
}
★编译时异常:必须要写
★运行时异常:可以不写
②throw
注意:卸载方法里面,结束方法,手动抛出异常对象,交给调用者,方法下面的代码不再执行l
public void 方法(){
throw new NullPointerException();
}
package com_07Gather_jinjie._04Exception._01ExceptionTest;
public class ExceptionTest11 {
public static void main(String[] args) {
/*
throws:写在方法定义处,表示声明一个异常。告诉调用者,使用本方法可能会有哪些异常。
throw :写在方法内,结束方法。手动抛出异常对象,交给调用者。方法中下面的代码不再执行了。
需求:
定义一个方法求数组的最大值
*/
int[] arr = null;
int max = 0;
try {
max = getMax(arr);
} catch (NullPointerException e) {
System.out.println("空指针异常");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界异常");
}
System.out.println(max);
}
public static int getMax(int[] arr)/* throws NullPointerException,ArrayIndexOutOfBoundsException*/ {
if (arr == null) {
//手动创建一个异常对象,并把这个异常交给方法的调用者处理
//此时方法就会结束,下面的代码不会再执行了
throw new NullPointerException();
}
if (arr.length == 0) {
//手动创建一个异常对象,并把这个异常交给方法的调用者处理
//此时方法就会结束,下面的代码不会再执行了
throw new ArrayIndexOutOfBoundsException();
}
System.out.println("看看我执行了吗?");
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
}
4.练习
需求:
键盘录入自己心仪的女朋友姓名和年龄。
姓名的长度在 3 - 10之间,
年龄的范围为 18 - 40岁,
超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示:
需要考虑用户在键盘录入时的所有情况。
比如:录入年龄时超出范围,录入年龄时录入了abc等情况
package com_07Gather_jinjie._04Exception._02ExceptionTest.Test01;
public class GirlFriend {
private String name;
private int age;
public GirlFriend() {
}
public GirlFriend(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
*
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
*
* @param name
*/
public void setName(String name) {
if (name.length() > 10 || name.length() < 3) {
throw new RuntimeException();
} else {
this.name = name;
}
}
/**
* 获取
*
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
*
* @param age
*/
public void setAge(int age) {
if (age > 40 || age < 18) {
throw new RuntimeException();
} else {
this.age = age;
}
}
public String toString() {
return "GirlFriend{name = " + name + ", age = " + age + "}";
}
}
//测试类
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
GirlFriend gf = new GirlFriend();
while (true) {
try {
System.out.println("请输入你女朋友的姓名");
gf.setName(sc.nextLine());
System.out.println("请输入你女朋友的年龄");
gf.setAge(Integer.parseInt(sc.nextLine()));
System.out.println(gf);
//如果所有数据都是正确的,跳出循环
break;
} catch (NumberFormatException e) {
e.printStackTrace();
continue;
} catch (RuntimeException e) {
System.out.println("姓名的长度或者年龄的范围有误");
continue;
}
}
}
}
5.自定义异常
(1)自定义异常的步骤:
①定义异常类(类名要见名知意)
②写继承关系
③空参构造
④带参构造
🔺意义:就是为了让控制台的报错信息更加的见名知意
//定义异常类
public class NameFormatException extends RuntimeException{
//起名的技技巧:
//NameFormat:姓名格式化问题
//Exception:当前类是一个异常类
//运行时异常:extends RuntimeException 核心:表示由于参数问题导致的异常
//编译时异常:extends Exception 核心:提醒程序员检查本地信息
public NameFormatException() {
}
public NameFormatException(String message) {
super(message);
}
public NameFormatException(String message, Throwable cause) {
super(message, cause);
}
public NameFormatException(Throwable cause) {
super(cause);
}
public NameFormatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
//定义第二个异常类
package com_07Gather_jinjie._04Exception._02ExceptionTest.Test02;
public class AgeOutOfBoundsException extends RuntimeException{
public AgeOutOfBoundsException() {
}
public AgeOutOfBoundsException(String message) {
super(message);
}
public AgeOutOfBoundsException(String message, Throwable cause) {
super(message, cause);
}
public AgeOutOfBoundsException(Throwable cause) {
super(cause);
}
public AgeOutOfBoundsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
//测试类
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
/*
需求:
键盘录入自己心仪的女朋友姓名和年龄。
姓名的长度在 3 - 10之间,
年龄的范围为 18 - 40岁,
超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示:
需要考虑用户在键盘录入时的所有情况。
比如:录入年龄时超出范围,录入年龄时录入了abc等情况
*/
Scanner sc = new Scanner(System.in);
GirlFriend gf = new GirlFriend();
while (true) {
try {
System.out.println("请输入你女朋友的姓名");
gf.setName(sc.nextLine());
System.out.println("请输入你女朋友的年龄");
gf.setAge(Integer.parseInt(sc.nextLine()));
System.out.println(gf);
//如果所有数据都是正确的,跳出循环
break;
} catch (NumberFormatException e) {
e.printStackTrace();
continue;
} catch (AgeOutOfBoundsException e) {
e.printStackTrace();
continue;
}
}
}
}
//姓名格式异常
Exception in thread "main" com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.NameFormatException: hfksdhfkqashf格式有误,长度范围3<=name.length()<=10
at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.GirlFriend.setName(GirlFriend.java:31)
at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.Test.main(Test.java:25)
//年龄范围异常
com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.AgeOutOfBoundsException: 67超出范围
at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.GirlFriend.setAge(GirlFriend.java:53)
at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.Test.main(Test.java:29)
二、File
1.什么是File
★File对象就白哦是一个路径,可以是文件的路径,也可以是文件夹的路径
★这个路径可以是存在的,也可以是不存在的
(1)常见的File类构造方法
方法名称 | 说明 |
---|---|
public File(String pathname) | 根据文件路径创建文件对象 |
public File(String parent,String child) | 根据父路径名字符串和子路径名字符串创建文件对象 |
public File(File parent,String child) | 根据父路径对应文件对象和子路径名字符串创建文件对象 |
import java.io.File;
public class FileTets01 {
public static void main(String[] args) {
//1.public File(String pathname) | 根据文件路径创建文件对象
File f1 = new File("C:\\User\\kinbow\\Desktop");
System.out.println(f1);
//2.public File(String parent,String child) | 根据父路径名字符串和子路径名字符串创建文件对象
//以"C:\\User\\kinbow\\Desktop\\a.txt"中的a.txt为例
//父级路径:C:\\User\\kinbow\\Desktop
//子级路径:a.txt
String parent = "C:\\User\\kinbow\\Desktop";
String child = "a.txt";
File f2 = new File(parent,child);
System.out.println(f2);
//自己拼接
File f3 = new File(parent+"\\"+child);
System.out.println(f3);
//3.public File(File parent,String child) | 根据父路径对应文件对象和子路径名字符串创建文件对象
File parent2 = new File("C:\\User\\kinbow\\Desktop");
String child2 = "a.txt";
File f4 = new File(parent2,child2);
System.out.println();
}
}
(2)小结
①File表示什么
★File对象表示路径,可以是文件、也可以是文件夹。
★这个路径可以是存在的,也可以是不存在的
②绝对路径和相对路径是什么意思
★绝对路径是带盘符的
★相对路径是不带盘符的,默认到当前项目下去找
③File三种构造方法的作用
★public File(String pathname) ===》把字符串表示的路径变成File对象
★public File(String parent,String child) ===》把父级路径和子级路径进行拼接
★public File(File parent,String child) ===》把父级路径和子级路径进行拼接
2.File的常见成员方法
(1)(判断、获取)
方法名称 | 说明 |
---|---|
public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 |
public bolean isFile() | 判断此路径名表示的File是否为文件 |
public boolean exists() | 判断此路径名表示的File是否存在 |
public long length() | 返回文件的大小(字节数量) |
public String getAbsolutePath() | 返回文件的绝对路径 |
public String getPath() | 返回定义文件时使用的路径 |
public String getName() | 返回文件的名称,带后缀 |
public long lastModified() | 返回文件的最后修改时间(时间毫秒值) |
import java.io.File;
import java.text.SimpleDateFormat;
public class FileTest02 {
public static void main(String[] args) {
/*方法名称 | 说明 |
| --------------------------------- | ------------------------------------ |
| public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 |
| public bolean isFile() | 判断此路径名表示的File是否为文件 |
| public boolean exists() | 判断此路径名表示的File是否存在 |
| public long length() | 返回文件的大小(字节数量) |
| public String getAbsolutePath() | 返回文件的绝对路径 |
| public String getPath() | 返回定义文件时使用的路径 |
| public String getName() | 返回文件的名称,带后缀 |
| public long lastModified() | 返回文件的最后修改时间(时间毫秒值) |
*/
//判断的方法
//1.对一个文件的路径进行判断
File f1 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
System.out.println(f1.isDirectory());//false
System.out.println(f1.isFile());//true
System.out.println(f1.exists());//true
System.out.println("\n"+"--------------------------------------------------");
//2.对一个文件夹的路径进行判断
File f2 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\ccc");
System.out.println(f2.isDirectory());//true
System.out.println(f2.isFile());//false
System.out.println(f2.exists());//true
System.out.println("\n"+"--------------------------------------------------");
//3.对一个不存在的路径进行判断
File f3 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\c.txt");
System.out.println(f3.isDirectory());//false
System.out.println(f3.isFile());//false
System.out.println(f3.exists());//false
System.out.println("\n"+"--------------------------------------------------");
//获取的方法
//1.public long length() | 返回文件的大小(字节数量)
//这个方法只能获取文件的大小,不能获取文件夹的大小,
//如果我们要获取一个文件及的大小,那么需要把这个文件及里面所有的文件大小都累加在一起
File f4 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
long length = f4.length();
System.out.println(length); //12字节
System.out.println("\n"+"--------------------------------------------------");
File f5 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\bbb");
long length2 = f4.length();
System.out.println(length); //0
System.out.println("\n"+"--------------------------------------------------");
//2.public String getAbsolutePath() | 返回文件的绝对路径
File f6 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
File absoluteFile = f6.getAbsoluteFile();
System.out.println(f6);//D:\workspace\idea_space\Java_based\study\src\com_07Gather_jinjie\_05File\aaa\a.txt
System.out.println("\n"+"--------------------------------------------------");
//3. public String getPath() | 返回定义文件时使用的路径
String path = f6.getPath();
System.out.println(path);//java\aaa\a.txt
System.out.println("\n"+"--------------------------------------------------");
//4.public String getName() | 返回文件的名称,带后缀
//细节:
//1.如果调用处是文件,那么返回的是文件名和后缀名
//2.如果调用处是文件夹,那么返回的是文件夹的名字
String name1 = f5.getName();
String name2 = f6.getName();
System.out.println(name1);//bbb
System.out.println(name2);//a.txt==>a:文件名 .txt:扩展名、后缀名
System.out.println("\n"+"--------------------------------------------------");
//5. public long lastModified() | 返回文件的最后修改时间(时间毫秒值)
long time = f6.lastModified();
System.out.println(time);//1685633005671
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(time);
System.out.println(format);
}
}
(2)创建、删除
方法名称 | 说明 |
---|---|
public boolean createNewFile() | 创建一个新的空文件 |
public boolean mkdir() | 创建单级文件夹 |
public boolean mkdirs() | 创建多级文件夹 |
public boolean delete() | 删除文件、空文件夹 |
注意:delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站
import java.io.File;
import java.io.IOException;
public class FileTest03 {
public static void main(String[] args) throws IOException {
//1.public boolean createNewFile() | 创建一个新的空的文件
//细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true
// 如果当前路径表示的文件是存在的,则创建失败,方法返回false
//细节2:如果父级路径是不存在的,那么方法会有异常,IOException:系统找不到指定的路径
//细节3:createNewFile()方法创建的一定是文件,如果路径当中不包含路径名,则会创建一个没有后缀名的而文件
File f1 = new File("D:\\abc.txt");
boolean b1 = f1.createNewFile();
System.out.println(b1);
//2.public boolean mkdir() | 创建单级文件夹(目录)
//细节1:Windows当中路径是唯一的,如果当前路径已经存在则无法创建,返回false
//细节2:mkdir方法啊只能创建单击文件夹,不能创建多级文件夹
File f2 = new File("D:\\ada");
boolean b2 = f2.mkdir();
System.out.println(b2);
//3.public boolean mkdirs() | 创建多级文件夹
//细节:mkdirs方法奴尽可以创建单击文件夹,也可以创建多级文件夹
File f3 = new File("D:\\bbb\\aaa\\ccc");
boolean b3 = f3.mkdirs();
System.out.println(b3);
//4.public boolean delete() | 删除文件、空文件夹
//细节:
//1.如果删除的是文件,那么直接删除,不走回收站,会彻底删除
//2.如果删除的是空文件夹,则直接删除,不走回收站
//3.如果删除的文件夹里面有文件或者有子文件夹,那么会删除失败,方法返回false
File f4 = new File("D:\\bbb\\aaa\\ccc" );
boolean b4 = f4.delete();
System.out.println(b4);
}
}
(3)获取并遍历
方法名称 | 说明 |
---|---|
public File [ ] listFiles() | 获取当前该路径下所有内容(重点掌握) |
public String [ ] list() | 获取当前该路径下所有内容 |
public static File [ ] listRoots() | 列出可用的文件系统权限 |
public String [ ] list(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
public File [ ] listFiles(FileFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
public File [ ] listFiles(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Arrays;
public class FileTest04 {
public static void main(String[] args) {
/* public File [ ] listFiles()获取当前该路径下所有内容(重点掌握)
* 细节:
* 1.当调用者File表示的路径不存在时,返回null
* 2.当调用者File表示的路径是文件时,返回null
* 3.当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
* 4.当调用者File表示的路径是一个有内容的文件夹时,将里面的所有文件和文件夹的路径放在File数组中返回
* 5.当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
* 6.当调用者File表示的路径是需要权限才能访问的文件夹时。返回null
* */
//1.创建File对象
File f1 = new File("D:\\aaa");
//2.listFiles() 获取文件夹里面的所有内容包括文件夹和文件
File[] files = f1.listFiles();
for (File file : files) {
//这里的file表示当前文件夹里面的每一个文件或文件夹
System.out.println(file);
}
System.out.println("\n"+"===================================================");
//2.public String [ ] list() | 获取当前该路径下所有内容(但是仅仅能获取名字)
File f2 = new File("D:\\aaa");
String[] arr2 = f2.list();
for (String s : arr2) {
System.out.println(s); //a.txt aaa abc.txt bbb
}
System.out.println("\n"+"===================================================");
//3.| public static File [ ] listRoots() | 列出可用的文件系统根
File[] arr = File.listRoots();
System.out.println(Arrays.toString(arr)); //[C:\, D:\, E:\, F:\]
System.out.println("\n"+"===================================================");
//4. public String [ ] list(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下所有内容
//假如说要获取某个文件夹里面的所有txt文件
File f3 = new File("D:\\aaa");
//accept方法的形参,依次表示当前文件夹下面的每一个文件或者文件夹
//参数一:父级路径
//参数二:子级路径
//返回值:如果返回值为true,就表示当前路径保留
// 如果返回值为falaw,就表示当前路径舍弃
String[] arr3 = f3.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File src = new File(dir, name);
return src.isFile() && name.endsWith(".txt");
}
});
System.out.println(Arrays.toString(arr3)); //[a.txt, abc.txt]
System.out.println("\n"+"===================================================");
//5.public File [ ] listFiles(FileFilter filter) | 利用文件名过滤器获取当前该路径下suoyouneir
File f4 = new File("D:\\aaa");
File[] arr4 = f4.listFiles();
//file依次表示当前文件夹下面的每一个文件夹或者文件
//第一种方法
for (File f : arr4) {
if (f.isFile() && f.getName().endsWith(".txt")){
System.out.println(f); //D:\aaa\a.txt D:\aaa\abc.txt
}
}
//第二种方法
File [] arr5 = f4.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith(".txt");
}
});
System.out.println(Arrays.toString(arr5));
System.out.println("\n"+"===================================================");
//6.public File [ ] list Files(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下suoyouneir
File[] arr6 = f4.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File src = new File(dir, name);
return src.isFile() && name.endsWith(".txt");
}
});
System.out.println(Arrays.toString(arr6));
}
}
三、综合案例
1.需求:在当前模块下的aaa文件夹中创建一个a.txt文件
import java.io.File;
import java.io.IOException;
public class FileTest01 {
public static void main(String[] args) throws IOException {
File f1 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
boolean newFile = f1.createNewFile();
System.out.println(newFile);
}
}
2.需求:定义一个方法,找某一个文件夹中,是否有以avi结尾的电影,暂时不考虑子文件夹
import java.io.File;
public class FileTest02 {
public static void main(String[] args) {
boolean b = searchFile1(new File("D:\\aaa"));
System.out.println(b);
}
public static boolean searchFile1(File file) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile() && f.getName().endsWith(".avi")) ;
return true;
}
return false;
}
}
3.需求:找到电脑中所有以avi结尾的电影。(需要考虑子文件夹)
import java.io.File;
public class FileTest03 {
public static void main(String[] args) {
/*
套路:
1,进入文件夹
2,遍历数组
3,判断
4,判断*/
searchAvi();
}
public static void searchAvi(){
//获取本地所有的盘符
File[] file = File.listRoots();
for (File f : file) {
searchFile(f);
}
}
public static void searchFile(File file){
//进入要查找的文件夹
File[] files = file.listFiles();
//遍历数组,依次得到每一个子文件夹
for (File f : files) {
if (f.isFile()){
//判断:如果是文件,就判断是不是以avi结尾的,如果是,打印该文件
if (f.getName().endsWith(".avi")){
System.out.println(f);
}
}else{
//判断,如果是文件夹,就递归,到子文件夹里找
//再次调用本方法的时候,参数一定是当前文件夹的子文件夹
searchFile(f);
}
}
}
}
4.需求:删除一个多级文件夹
import java.io.File;
public class FileTest04 {
public static void main(String[] args) {
/*
删除一个多级文件夹
如果我们要删除一个有内容的文件夹
1.先删除文件夹里面所有的内容
2.再删除自己
*/
File file = new File("D:\\aaa");
deleteFile(file);
}
public static void deleteFile(File file){
//进入当前文件夹
File[] files = file.listFiles();
//遍历,得到当前文件夹里面的每一个文件或者而文件夹
for (File f : files) {
//判断,如果当前是文件,就直接删除
if (f.isFile()){
f.delete();
}else {
//如果是文件夹,就到子文件夹里
deleteFile(f);
}
}
//子文件夹里面的文件全部删掉了,再删除本身这个文件夹
file.delete();
}
}
5.需求统:计一个文件夹的总大小
import java.io.File;
public class FileTest05 {
public static void main(String[] args) {
File file = new File("D:\\aaa");
}
/*
* 作用:
* 统计一个文件夹的总大小
* 参数:
* 表示要统计的那个文件夹
* 返回值:
* 统计之后的结果
*
* 文件夹的总大小:
* 说白了,文件夹里面所有文件的大小
* */
public static long getLen(File file){
//定义变量进行文件大小的累加
long len= 0;
//进入当前文件夹
File[] files = file.listFiles();
//遍历
for (File f : files) {
//判断:如果当前是文件,就获取长度,赋值给len
if (f.isFile()){
len = len +f.length();
}else {
//如果是文件夹,就递归,找到子文件夹进行判断,
//如果这个文件夹是空的,就把大小传递给len
len = len + getLen(f);
}
}
//将大小len返回
return len;
}
}
6.需求:统计一个文件夹中每种文件的个数并打印。(考虑子文件夹)
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class FileTest06 {
public static void main(String[] args) {
/*
打印格式如下:
txt:3个
doc:4个
jpg:6个
*/
File file = new File("D:\\aaa");
HashMap<String,Integer> hm = getFileCount(file);
System.out.println(hm);
}
public static HashMap<String,Integer> getFileCount(File src){
//1.定义集合用来统计
HashMap<String,Integer> hm = new HashMap<>();
//2.进入src文件夹
File[] files = src.listFiles();
//3.遍历数组
for (File file : files) {
//4.判断,如果是文件,统计
if(file.isFile()){
//a.txt
String name = file.getName();
String[] arr = name.split("\\.");
if(arr.length >= 2){
String endName = arr[arr.length - 1];
if(hm.containsKey(endName)){
//存在
int count = hm.get(endName);
count++;
hm.put(endName,count);
}else{
//不存在
hm.put(endName,1);
}
}
}else{
//5.判断,如果是文件夹,递归
//sonMap里面是子文件中每一种文件的个数
HashMap<String, Integer> sonMap = getFileCount(file);
//hm: txt=1 jpg=2 doc=3
//sonMap: txt=3 jpg=1
//遍历sonMap把里面的值累加到hm当中
Set<Map.Entry<String, Integer>> entries = sonMap.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
int value = entry.getValue();
if(hm.containsKey(key)){
//存在
int count = hm.get(key);
count = count + value;
hm.put(key,count);
}else{
//不存在
hm.put(key,value);
}
}
}
}
return hm;
}
}