文章目录
- File >> 存储数据的方案
- 1. 认识File
- 2. File操作
- 2.1 创建File对象
- 2.2 File操作
- 1)对文件对象的信息的操作
- 2)文件/文件夹的创建/删除
- 3)⭐⭐对文件夹的遍历
- 3. 方法递归
- 3.1 认识递归
- 3.2 递归算法及其执行流程
- 1) 案例:
- 2) 递归算法的三要素:
- 3) 🤔练习:猴子吃桃问题
- 3.3 ⭐递归实现文件搜索
- 4. 字符集
- 4.1 常见字符集介绍
- 4.2 字符集的编码、解码操作
- 1)编码
- 2)解码
File >> 存储数据的方案
1. 认识File
开发中需要长久保存的数据,可以保存在磁盘的文件中,即使断电后也不会丢失
File
是java.io.
包下的类,File
类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹),只能操作文件本身
2. File操作
2.1 创建File对象
File file = new File("文件/文件夹/绝对路径/相对路径");
// public File(String pathname):通过将给定的路径名字符串转换为表示绝对路径名字符串来创建一个新File实例。
// public File(String parent, String child):从父路径名字符串和子路径名字符串创建一个新File实例。
// public File(File parent, String child):从父目录和子路径名字符串创建一个新File实例。
// File f11 = new File("F:\\Pictures\\江晏.png"); 反斜杠的路径:双反斜杠
File f1 = new File("F:/Pictures/江无浪.png");
2.2 File操作
1)对文件对象的信息的操作
System.out.println(f1.getName()); // 文件名
System.out.println(f1.getParent()); // 父路径
System.out.println(f1.getPath()); // 路径System.out.println(f1.length()); // 字节个数
System.out.println(f1.lastModified()); // 最后修改时间
System.out.println(f1.isFile()); // 是否是文件
System.out.println(f1.isDirectory()); // 是否是文件夹// 可以使用相对路径定位文件对象
// 只要带有盘符的路径都称之为绝对路径
// 相对路径:不带盘符,默认是到你的idea工程下直接寻找文件的。一般用来找工程下的项目文件的
System.out.println(f1.getAbsolutePath()); // 绝对路径
2)文件/文件夹的创建/删除
// 3、创建对象代表不存在的文件路径\文件夹
File f2 = new File("F:/Users/Juzi/Pictures/江晏1.png");
System.out.println(f2.exists()); // 判断文件是否存在
System.out.println(f2.createNewFile()); // 创建文件// 4、创建对象代表不存在的文件夹
// mkdir():创建单级文件夹
File dir1 = new File("F:/Users/Juzi/Pictures/dir1");
System.out.println(dir1.mkdir());
// mkdirs():创建多级文件夹
File dir2 = new File("F:/Users/Juzi/Pictures/dir1/dir2/dir3");
System.out.println(dir2.mkdirs());// 5、创建File对象代表存在的文件,然后删除它
File f3 = new File("F:/Users/Juzi/Pictures/江晏.png");
System.out.println(f3.delete());// 6、创建File对象代表存在的文件夹,然后删除它
// 只能删除空文件夹
File dir3 = new File("F:/Users/Juzi/Pictures/dir1");
System.out.println(dir3.delete());
3)⭐⭐对文件夹的遍历
💡可以通过获取的文件对象数组是长度为0还是为null,来判断该文件夹是为空还是没有权限访问,从而采取措施提高代码的健壮性。
// 7、遍历文件夹的方法
// public String[] list():获取当前目录下的所有子项,以字符串数组的形式返回。
// public File[] listFiles():获取当前目录下的所有子项,以File数组的形式返回。
File names = new File("F:/Users/Juzi/Pictures");
String[] namelist = names.list();
for (String name : namelist){System.out.println(name);
}
// 获取的是文件对象,然后可以操作文件
File[] files = names.listFiles();
for (File file : files){System.out.println(file);
}
3. 方法递归
3.1 认识递归
- 一种算法
- 从形式上:方法调用自身的形式 >>> 递归
- 直接递归:方法自己调用自己
- 间接递归:方法调用其他方法,其他方法又回调方法自己
- 需注意的问题:
- 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误
public static void main(String[] args) {// 目标:认识递归的形式print(3);
}public static void print(int n) {if (n > 0) {print(n - 1); // 递归调用:自己调自己System.out.print(n + "\t");}
}
3.2 递归算法及其执行流程
1) 案例:
- 需求:计算n的阶乘
- 分析
- 公式:
f(n) = 1 * 2 * 3 * 4 * ...(n-1) * n
; - 递归写法:
f(n) = f(n-1) * n
- 公式:
public static void main(String[] args) {// 目标:计算n的阶乘System.out.println(factorial(5)); // 120
}public static int factorial(int n) {if (n == 1) {return 1;}return n * factorial(n - 1);
}
- 递归调用的流程
先一层一层入栈,再一层一层出栈
2) 递归算法的三要素:
- 递归公式:
f(n) = f(n-1) * n
- 递归的终结点:
f(1)
- 递归的方向必须走向终结点
3) 🤔练习:猴子吃桃问题
猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。
求第一天共摘多少个桃子?
分析:
-
每天都是同一个事件:当天桃子数量的一半 + 1
-
递归公式:
f ( n + 1 ) = f ( n ) − f ( n ) / 2 − 1 → f ( n ) = 2 f ( n + 1 ) + 2 f(n+1) = f(n)-f(n)/2-1 \quad →f(n) = 2f(n+1) + 2 f(n+1)=f(n)−f(n)/2−1→f(n)=2f(n+1)+2 -
递归的终结点:
f(10) = 1
-
递归的方向必须走向终结点
public static void main(String[] args) {// 猴子吃桃System.out.println(peachCount(1)); // 1534// 第一天的桃子数量 peachCount(1)
}public static int peachCount(int day){if(day == 10){return 1;}return (peachCount(day + 1) + 1) * 2;
}
3.3 ⭐递归实现文件搜索
-
需求:从E:盘中,搜索 “ QQ.exe ” 文件,找出后输出其位置
-
分析:
- 先找出E:盘下的所有一级文件对象
- 遍历全部一级文件对象,判断是否是文件
- 是文件 → 判断是否是自己想要的
- 是文件夹,需要继续进入到该文件夹,重复上述过程
public static void main(String[] args) {// 目标:完成文件搜索// 1、定义一个方法,实现文件搜索功能。// 2、在main方法中调用该方法,并测试。File dirPath = new File("E:/");searchFile(dirPath, "QQ.exe");
}/*** 递归实现文件搜索* @param dirPath 搜索的目录路径* @param fileName 要搜索的文件名*/
public static void searchFile(File dirPath, String fileName){// 1、判断极端情况: 判断当前目录是否存在,并且是文件夹,并且不是文件// ① 当前目录是否有权限访问 || ② 当前目录是否存在 || ③ 当前目录是否是文件if(dirPath == null || !dirPath.exists() || dirPath.isFile()){System.out.println("搜索的文件不存在!");return;}// 2、获取目录下的所有一级文件或者文件夹对象File[] files = dirPath.listFiles();// 2.1 考虑极端情况:判断当前目录下是否存在一级文件对象,存在才可以遍历// files != null 》》》 当前目录有权限拿// files.length > 0 》》》 当前目录有一级文件对象if(files!=null && files.length>0){// 3、遍历一级文件对象,判断是文件还是文件夹for (File file : files){if(file.isFile()){// 4、判断文件名是否匹配if(file.getName().contains(fileName)){System.out.println("找到文件:" + file.getAbsoluteFile());}}else{// 5、递归搜索子文件夹searchFile(file, fileName);}}}
}
📓关于 if 条件语句中的判断 >>> 遍历文件的 listfiles() 方法中各返回值的明细
4. 字符集
4.1 常见字符集介绍
- 标准ASCII字符集
- 包含英文、符号等
- 使用1个字节(8位)存储一个字符,首位是0,总共可表示128个字符
- GBK(汉字内码扩展规范,国标)
- 汉字编码字符集,包含2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
- GBK兼容了ASCII字符集
- 汉字的第一个字节的第一位必须是1
- Unicode字符集(统一码)
- 国际组织制定的,可以容纳世界上所有文字、符号的字符集
- UTF-8字符集:
- Unicode字符集的一种编码方案
- 采用可变长编码方案:前缀码
- 共四个长度区:1个字节(英文、数字),2个字节,3个字节(汉字),4个字节
可变长编码
4.2 字符集的编码、解码操作
⚠️字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
⚠️英文、数字一般不会乱码,因为很多字符集兼容了ASCII码
1)编码
getBytes()方法
:将字符串转换为字节数组
getBytes(String charsetName)
:指定编码方式,将字符串转换为字节数组
String str = "你好";byte[] bytes = str.getBytes(); // 默认使用UTF-8编码
System.out.println(bytes.length); // 6
System.out.println(Arrays.toString(bytes)); // [-28, -67, -96, -27, -91, -67]byte[] gbks = str.getBytes("GBK");
System.out.println(gbks.length); // 4
System.out.println(Arrays.toString(gbks)); // [-60, -29, -70, -61]
2)解码
String(byte[] bytes)
:默认使用UTF-8解码
String(byte[] bytes, String charsetName)
:指定编码方式,将字节数组解码为字符串
String str2 = new String(bytes);
System.out.println(str2); // 你好String str3 = new String(gbks, "GBK");
System.out.println(str3); // 你好