练习1:在当前模块下的aaa文件夹中创建一个a.txt文件。
分析:当前模块下是没有aaa文件夹的,这里我是手动在当前模块下创建了aaa文件夹,然后在指定a.txt的路径,再createNewFile()的。
public class File1 {
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Administrator\\Desktop\\aaa\\a.txt";
File file = new File(path);
file.createNewFile();
}
}
修改:手动在当前模块下创建aaa文件夹是有问题的,需要用代码创建aaa文件夹,然后再createNewFile()文件a.txt,修改后的代码如下:
public class File1 {
public static void main(String[] args) throws IOException {
File file = new File("aaa");
file.mkdirs();
new File(file,"a.txt").createNewFile();
}
}
练习2:定义一个方法,找某一个文件夹中是否有以avi结尾的电影。(暂时不考虑子文件夹)
这里我将需求修改为是否有以png结尾的图片。
分析:
- 首先的到文件夹下的所有内容:listFiles()
- 通过遍历依次得到文件夹下的每一个文件或者文件夹
- 然后获取名字,并比较是否以png结尾
public class File2 {
public static void main(String[] args) {
File file = new File("D:\\Java学习资料\\day27-IO(异常&File&综合案例)\\笔记\\imgs");
File[] files = file.listFiles();
for (File file1 : files) {
if(file1.getName().endsWith("png"))
System.out.println(file1);
}
}
}
修改:还有一点就是需要判断是否为文件。然后也并没有根本要求将其定义为方法,所以使用crtl+alt+M抽取为一个方法命名为contains,
public class File2 {
public static void main(String[] args) {
File file = new File("D:\\Java学习资料\\day27-IO(异常&File&综合案例)\\笔记\\imgs");
System.out.println(contains(file));
}
private static boolean contains(File file) {
File[] files = file.listFiles();
for (File f : files) {
if(f.isFile() && f.getName().endsWith("png"))
return true;
}
return false;
}
}
练习3:找到电脑中所以以avi结尾的电影,需考虑子文件夹。
实现:自己是没有什么思路的。
学习:视频中讲解的是使用递归的思想。
关于递归必须有终止条件,即在什么时候不会再递归下去。这里是当遍历的文件夹下都是文件时递归终止。
思路:
- 首先的到文件夹下的所有内容:listFiles()
- 通过遍历依次得到文件夹下的每一个文件或者文件夹
- 然后如果是文件则获取名字,并比较是否以png结尾
- 如果是文件夹则递归调用此方法
还有一个问题运行时可能会出现空指针异常,为什么呢?
在访问文件夹时需要注意,因为有的文件夹是没有权限访问的,此时调用listFiles()方法的返回值为null。所以变量files有可能为空,如果为空则在运行时会报空指针异常,为了避免这种情况,所以要加一个判断:if (files != null)。
运算符:!=,不等于
public class File3 {
public static void main(String[] args) {
File file = new File("D:\\Java学习资料\\day27-IO(异常&File&综合案例)\\笔记");
findPNG(file);
}
private static void findPNG(File file) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile() && f.getName().endsWith("png")) {
System.out.println(f);
} else {
findPNG(f);
}
}
}
}
}
思考:以前只有一个进行递归,这里是数组中的多个进行递归。优先深度再广度。
练习4:删除一个多级文件夹。
从里往外删。
这里是当文件夹下没有文件夹时递归终止。
当删除文件夹下的所有内容时,却忘记删除原来的文件夹,这是因为我只考虑什么时候递归往下进行,却没考虑递归什么时候回来。
如何使用递归去解决问题呢?当使用递归时应该如何思考呢?
public class File4 {
public static void main(String[] args) {
delete(new File("C:\\Users\\Administrator\\Desktop\\aaa"));
}
public static void delete(File file) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory()) {
delete(f);
}
else {
f.delete();
}
}
file.delete();
}
}
练习5:统计一个文件夹的总大小。
这里我是定义了一个共享变量。
public class file5 {
static long sumLength = 0;
public static void main(String[] args) {
System.out.println(countLength(new File("D:\\Java学习资料\\day27-IO(异常&File&综合案例)\\笔记")));
}
private static long countLength(File file) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile()) {
sumLength += f.length();
} else {
countLength(f);
}
}
}
return sumLength;
}
}
输出结果:
我这种方法是有弊端的,因为在实际使用countLength这个方法的时候怎么可能再额外定义一个静态变量,根本不合理。
所以视频里的思路是将记录大小的变量len定义为局部变量。
这种思路下只需考虑此文件夹下所有文件的大小和子文件夹总的大小。而子文件夹的大小如何计算是不用管的。
public class demo2 {
public static void main(String[] args) {
System.out.println(countLength(new File("D:\\Java学习资料\\day23-集合(泛型&Set&数据结构)\\笔记")));
}
public static long countLength(File file) {
long len = 0;
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile()) {
len += f.length();
} else {
len += countLength(f);
}
}
}
return len;
}
}
练习6:统计一个文件夹中每种文件的个数并打印。(考虑子文件夹)
打印格式如下:
txt:3个
doc:4个
jpg:6个
(1)如何统计?
对于这个练习,如果使用普通的变量去统计,并不知道有什么类型的文件,也就不知道要定义多少个变量去统计,所以就用到了Map集合。
刚开始依然想把HashMap定义为静态变量,其实是不合适的。后面定义为局部变量。
(2)思路:
首先将一个文件夹下的每种文件类型用HashMap存储起来
但是子文件中的HashMap如何合并呢?
取出sonMap中的所有key,判断是否在父文件夹的HashMap中存在,如果存在则两个Map中的值直接相加,不存在则放上去。
(3)HashMap中有一个方法是用来判断key是否存在的:containsKey()。
(4)但是我没有考虑到的一种情况就是没有后缀名的文件,在这种情况下进行切割的返回值直接就是文件名,而我们是不统计没有后缀名的文件的,所以要增加一个判断:if (str.length >= 2)
public class demo4 {
public static void main(String[] args) {
HashMap<String, Integer> hm = count(new File("src"));
for (Map.Entry<String, Integer> entry : hm.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue() + "个");
}
}
public static HashMap<String, Integer> count(File file) {
HashMap<String,Integer> hashMap = new HashMap<>();
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile()) {
String[] str = f.getName().split("\\.");
if (str.length >= 2) {
String name = str[str.length - 1];
if (hashMap.containsKey(name)) {
int count = hashMap.get(name);
count++;
hashMap.put(name, count);
} else {
hashMap.put(name, 1);
}
}
}
else {
HashMap<String, Integer> hashMap1 = count(f);
Set<String> names = hashMap1.keySet();
for (String name : names) {
if (hashMap.containsKey(name)) {
hashMap.put(name, hashMap.get(name) + hashMap1.get(name));
} else {
hashMap.put(name, hashMap1.get(name));
}
}
}
}
}
return hashMap;
}
}