7.1 File类的基本操作(一)

系列 -

本节实验主要学习Java中的文件操作,包括文件的创建、删除、目录遍历等基本操作。通过实验,你将掌握Java中File类的基本使用方法。

首先我们来学习如何创建和删除文件。下面的代码演示了文件操作的基本流程:

java

import java.io.File;  
  
public class Example01 {  
    public static void main(String[] args) {  
        /**  
         * Step 1 创建普通文件  
         */  
        // 创建File对象,指定文件路径
        File file1 = new File("out/chapter7/file1.txt");  
        if (file1.exists()) {  
            // 如果文件存在就删除  
            System.out.println("文件存在");  
            file1.delete();  
            System.out.println("文件已删除");  
        } else {  
            // 如果文件不存在就创建  
            System.out.println("文件不存在");  
  
            try {  
                file1.createNewFile();  
                System.out.println("文件已创建");  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
  
        System.out.println("\n");  
    }  
}

上面的代码会出现异常,因为在创建文件之前,我们需要确保文件所在的目录存在。以下代码展示了如何创建目录:

注意
  • mkdirs()方法可以创建多级目录
  • mkdir()只能创建单级目录
  • 创建文件前必须确保父目录存在
引用
目录(文件夹)本质上也是文件

Java提供了多种遍历目录的方式。以下是两个常用的例子:

1、简单遍历:

java

import java.io.File;  
  
public class Example03 {  
    public static void main(String[] args) {  
        File file = new File("src");  
        if (file.isDirectory()) {  
            System.out.println("是目录");  
            String[] names = file.list();  
            for (String name : names) {  
                System.out.println(name);  
            }  
        }  
    }  
}

2、带过滤器的遍历:

java

import java.io.File;  
import java.io.FilenameFilter;  
  
public class Example04 {  
    public static void main(String[] args) {  
        // 创建 File 对象  
        File file = new File("src");  
        // 创建过滤器对象  
        FilenameFilter filter = new FilenameFilter() {  
            // 实现 accept 方法  
            @Override  
            public boolean accept(File currFile, String name) {  
                if (currFile.isFile() && name.endsWith(".java")) {  
                    return true;  
                } else {  
                    return false;  
                }  
            }  
        };  
  
        if (file.exists() && file.isDirectory()) {  
            String[] names = file.list(filter);  
            for (String name : names) {  
                System.out.println(name);  
            }  
        }  
    }  
}

前面的例子演示的都是遍历目录下文件的文件名,有时候在一个目录下,除了文件,还有子目录,如果想得到所有子目录下的File类型对象,list()方法显然不能满足要求,这时需要使用File类提供的另一个方法listFiles()

listFiles()方法返回一个File对象数组,当对数组中的元素进行遍历时,如果元素的类型是目录,则需要使用递归。

java

import java.io.File;  
  
public class Example05 {  
    public static void main(String[] args) {  
        File file = new File("src");  
        showFiles(file);  
    }  
  
    /**  
     * 显示指定目录下的所有文件  
     * @param dir 目录  
     */  
    public static void showFiles(File dir) {  
        // 获取当前目录下所有文件的数组  
        File[] fileArray = dir.listFiles();  
        for (File file : fileArray) {  
            if (file.isDirectory()) {  
                // 如果是目录就递归调用  
                showFiles(file);  
            }  
            // 打印文件的绝对路径  
            System.out.println(file.getAbsolutePath());  
        }  
    }  
}

首先在电脑的D盘中创建一个名称为hello的文件夹,然后在文件夹中创建一个文本文件,接下来创建一个类Example06,在Example06类中使用delete()方法删除文件夹

java

import java.io.File;  
  
public class Example06 {  
    public static void main(String[] args) {  
        File file = new File("d:/hello");  
        if (file.exists()) {  
            if (file.delete()) {  
                System.out.println("删除成功!");  
            } else {  
                System.out.println("删除失败!");  
            }   
        }  
    }  
}

删除失败的原因是File类的delete()方法只能删除一个指定的文件,假如File对象代表目录,并且目录下包含子目录或文件,则File类的delete()方法不允许对这个目录直接删除。

在这种情况下,需要通过递归的方式将整个目录以及其中的文件全部删除。

java

import java.io.File;  
  
public class Example07 {  
    public static void main(String[] args) {  
        File dir = new File("d:/hello");  
        deleteFiles(dir);  
    }  
  
    /**  
     * 删除指定目录下的所有文件(包括子目录)  
     * @param dir 目录  
     */  
    public static void deleteFiles(File dir) {  
        if (dir.exists()) {  
            File[] files = dir.listFiles();  
            // 删除当前目录下的所有文件  
            for (File file : files) {  
                // 如果是目录就递归调用  
                if (file.isDirectory()) {  
                    deleteFiles(file);  
                } else {  
                    // 如果是文件就删除  
                    file.delete();  
                }  
            }  
            // 删除当前目录  
            dir.delete();  
        }  
    }  
}
注意
删除是直接删除而不放入回收站,文件一旦删除就无法恢复,因此在进行删除操作的时候需要格外小心。

在遍历目录的代码中,我们使用了匿名内部类来创建过滤器。这是Java中一个重要的概念:

java

FilenameFilter filter = new FilenameFilter() {
    @Override
    public boolean accept(File currFile, String name) {
        // 方法实现
    }
};

这种写法相当于:

  1. 定义了一个实现FilenameFilter接口的类(没有名字,所以叫匿名类)
  2. 创建了这个类的对象
  3. 把对象赋值给filter变量

等价的常规写法如下;

java

// 先定义一个实现类
class MyFilter implements FilenameFilter {
    @Override
    public boolean accept(File currFile, String name) {
        if (currFile.isFile() && name.endsWith(".java")) {
            return true;
        } else {
            return false;
        }
    }
}

// 然后创建对象
FilenameFilter filter = new MyFilter();

编写一个程序,实现以下功能:

  1. 搜索指定目录下的所有以.txt结尾的文件
  2. 将找到的文件名和文件大小打印出来
  3. 最后统计找到的文件总数

参考代码框架:

java

import java.io.File;
import java.io.FilenameFilter;

public class FileSearcher {
    public static void main(String[] args) {
        // 请将此处替换为你的目录路径
        File directory = new File("D:\\test");

		// 检查目录是否存在,若不存在需要给出提示,并退出程序
        
        // 待实现:创建文件过滤器,只接受.txt文件
        FilenameFilter filter = null;  // 在此处修改,实现文件过滤器
        
        // 待实现:遍历目录,打印文件信息
        
        // 待实现:统计文件总数
    }
}
  1. 使用匿名内部类实现FilenameFilter
  2. 文件大小要求显示为KB为单位
  3. 要处理目录不存在的情况

text

文件名:test1.txt,大小:1.5 KB
文件名:test2.txt,大小:2.3 KB
文件名:note.txt,大小:0.5 KB
共找到 3 个txt文件

编写一个程序,实现以下功能:

  1. 深层搜索指定目录下的所有以.java结尾的文件
  2. 将找到的文件名和文件大小打印出来
  3. 删除找到的文件
  4. 最后统计删除的文件总数
  1. 使用匿名内部类实现FilenameFilter
  2. 文件大小要求显示为KB为单位
  3. 要处理目录不存在的情况

text

文件名:test1.java,大小:1.5 KB
文件名:test2.java,大小:2.3 KB
文件名:note.java,大小:0.5 KB
已删除 test1.java
已删除 test2.java
已删除 note.java
共删除 3 个java文件

相关内容