Java 入门指南:Java IO流 —— 文件类

File 流

在 IO 操作中,文件的操作相对来说是比较复杂的,但也是使用频率最高的部分,几乎所有的项目中几乎都有一个叫做 FileUtil 或者 FileUtils 的工具类。

java.io.File 类是专门对文件进行操作的类,注意只能对文件本身进行操作,不能对文件内容进行操作(与流无关),想要操作内容,必须借助输入输出流

File 类是文件和目录的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

File 可以表示 C:\\文件目录1C:\\文件目录1\\文件.txt ,前者是文件夹(Directory,或者叫目录)后者是文件(file)

File 构造方法

在 Java 中,一切皆是对象,File 类也不例外,不论是哪个对象都应该从该对象的构造说起,所以我们来分析分析File类的构造方法。

比较常用的构造方法有三个:

1、 File(String pathname) :通过给定的路径来创建新的 File 实例。

2、 File(String parent, String child) :从父路径(字符串)和子路径创建新的 File 实例。

3、 File(File parent, String child) :从父路径(File)和子路径名字符串创建新的 File 实例。

macOS 路径使用正斜杠(/)作为路径分隔符,而 Windows 路径使用反斜杠(\)作为路径分隔符。所以在遇到路径分隔符的时候,不要直接去写/或者\

Java 中提供了一个跨平台的方法来获取路径分隔符,即使用 File.separator,这个属性会根据操作系统自动返回正确的路径分隔符。

File 类的注意点

  1. 一个 File 对象代表硬盘中实际存在的一个文件或者目录。
  2. File 类的构造方法不会检验这个文件或目录是否真实存在,因此无论该路径下是否存在文件或者目录,都不影响 File 对象的创建。

绝对路径和相对路径

绝对路径是从文件系统的根目录开始的完整路径,它描述了一个文件或目录在文件系统中的确切位置。

在 Windows 系统中,绝对路径通常以盘符(如 C:)开始,例如 “C:\Program Files\Java\jdk1.8.0_291\bin\java.exe”。

在 macOS 和 Linux 系统中,绝对路径通常以斜杠(/)开始,例如 “/usr/local/bin/python3”。

相对路径相对于当前工作目录的路径,它描述了一个文件或目录与当前工作目录之间的位置关系。

在 Java 中,相对路径通常是相对于当前 Java 程序所在的目录,例如 “config/config.properties”。如果当前工作目录是 “/Users/username/project”,那么相对路径 “config/config.properties” 就表示 “/Users/username/project/config/config.properties”。

注意

  • Windows 操作系统中,文件系统默认是不区分大小写的,即在文件系统中,文件名和路径的大小写可以混合使用。例如,“C:\Users\username\Documents\example.txt” 和 “C:\Users\Username\Documents\Example.txt” 表示的是同一个文件。

    但是,Windows 操作系统提供了一个区分大小写的选项,可以在格式化磁盘时选择启用,这样文件系统就会区分大小写。

  • 在 macOS 和 Linux 等 Unix 系统中,文件系统默认是区分大小写的。例如,在 macOS 系统中,“/Users/username/Documents/example.txt” 和 “/Users/username/Documents/Example.txt” 表示的是两个不同的文件。

File 操作

「File」 即文件操作,通常和计算机的磁盘打交道,这也是最基本的操作了。在我们平时操作文件的时候,有文件夹和文件操作,基本的创建、修改、删除等操作,在Java中是 「File」 类去做的一些相关操作,所以我们需要先实例化它。

File 常见方法

获取功能的方法
  1. getAbsolutePath():返回此 File 的绝对路径。

  2. getPath():结果和 getAbsolutePath 一致。

  3. getName():返回文件名或目录名。

  4. length():返回文件长度,以字节为单位。

判断功能的方法
  1. exists() :判断文件或目录是否存在。

  2. isDirectory() :判断是否为目录。

  3. isFile() :判断是否为文件。

创建、删除功能的方法
  1. createNewFile() :文件不存在,创建一个新的空文件并返回true,文件存在,不创建文件并返回false

  2. delete() :删除文件或目录。如果是目录,只有目录为空才能删除。

  3. mkdir() :只能创建一级目录(一个文件夹),如果父目录不存在,则创建失败。返回 true 表示创建成功,返回 false 表示创建失败。

  4. mkdirs() :可以创建多级目录,如果父目录不存在,则会一并创建。返回 true 表示创建成功,返回 false 表示创建失败或目录已经存在。

开发中一般用 mkdirs();

目录的遍历
  • String[] list() :返回一个 String 数组,表示该 File 目录中的所有子文件或目录。

  • File[] listFiles() :返回一个 File 数组,表示该 File 目录中的所有的子文件或目录。

listFiles() 在获取指定目录下的文件或者子目录时必须满足下面两个条件:1. 指定的目录必须存在
2. 指定的必须是目录。否则容易引发 NullPointerException 异常

文件属性相关操作
  File txt1 = new File("test1.txt");
  Log.info("获取父路径 ---->" + new File (txt1.getAbsolutePath()).getParent());

  Log.info("文件大小---->" + txt1.length() + "byte"); // 0 byte

  Log.info("文件是否隐藏----->" + txt1.isHidden()); // false

  Log.info("文件是否可读----->" + txt1.canRead()); // true

  Log.info("文件是否可写----->" + txt1.canWrite()); // true

  Log.info("获取文件路径---->" + txt1.getPath()); // test1.txt

  // 属性设置
  txt1.setReadable(false);   // 是否可读
  
  txt1.setWritable(false);   // 是否可写
  
  txt1.setExecutable(false); // 是否可执行
  
  txt1.setLastModified(new Date().getTime()); // 最后修改时间
  
  txt1.setReadOnly();        // 设置只读

RandomAccessFile

RandomAccessFile 是 Java 中一个非常特殊的类,它既可以用来读取文件,也可以用来写入文件。

与其他 IO 类(如 FileInputStreamFileOutputStream)不同,RandomAccessFile 允许跳转到文件的任何位置,从那里开始读取或写入。这使得它特别适用于需要在文件中随机访问数据的场景,如数据库系统。

构造方法

RandomAccessFile 的构造方法如下,可以指定 mode(读写模式)。
![[RandomAccessFile.png]]

RandomAccessFile 主要有两个构造方法:

  • RandomAccessFile(File file, String mode):使用给定的文件对象和访问模式创建一个新的 RandomAccessFile 实例。

  • RandomAccessFile(String name, String mode):使用给定的文件名和访问模式创建一个新的 RandomAccessFile 实例。

读写模式主要有下面四种:

  • r : 以只读模式打开文件。调用结果对象的任何 write 方法都将导致 IOException。

  • rw: 以读写模式打开文件。如果文件不存在,它将被创建

  • rws: 相对于 rwrws 要求对内容或元数据的每个更新都被立即写入到底层存储设备。这种模式是同步的,可以确保在系统崩溃时不会丢失数据

  • rwd : 与 rws 类似,以读写模式打开文件,但仅要求对文件内容的更新被立即写入。元数据可能会被延迟写入。

文件内容 指的是文件中实际保存的数据,
元数据 则是用来描述文件属性比如文件的大小信息、创建和修改时间。

常用方法

  • long getFilePointer():返回文件指针的当前位置。

  • long length():返回此文件的长度。

  • int read():从该文件中读取一个字节数据。

  • int read(byte[] b):从该文件中读取字节数据并将其存储到指定的字节数组中。

  • int read(byte[] b, int off, int len):从该文件中读取字节数据并将其存储到指定的字节数组中,从偏移量 off 开始,最多读取 len 个字节。

  • String readLine():从该文件中读取一行文本。

  • readUTF():从文件读取 UTF-8 编码的字符串。此方法首先读取两个字节的长度信息,然后根据这个长度读取字符串的 UTF-8 字节。最后,这些字节被转换为 Java 字符串。
    当使用 readUTF 方法读取字符串时,需要确保文件中的字符串是使用 writeUTF 方法写入的,这样它们之间的长度信息和编码方式才能保持一致。

  • void seek(long pos):将文件指针设置到文件中的 pos 位置。

  • void write(byte[] b):将指定的字节数组的所有字节写入该文件。

  • void write(byte[] b, int off, int len):将指定字节数组的部分字节写入该文件,从偏移量 off 开始,写入 len 个字节。

  • void write(int b):将指定的字节写入该文件。

  • writeUTF(String str):将一个字符串以 UTF-8 编码写入文件。此方法首先写入两个字节的长度信息,表示字符串的 UTF-8 字节长度,然后写入 UTF-8 字节本身。
    当使用 writeUTF 写入字符串时,实际写入的字节数会比字符串的 UTF-8 字节长度多两个字节。这两个字节用于在读取字符串时确定正确的字符串长度。

Apache FileUtils 类

FileUtils 类是 Apache Commons IO 库中的一个类,提供了一些更为方便的方法来操作文件或目录。

需要在官网下载 jar包 或在 Maven 中添加依赖:Maven Repository: commons-io » commons-io (mvnrepository.com)

Hutool FileUtil 类

FileUtil 类是 Hutoolopen in new window 工具包中的文件操作工具类,提供了一系列简单易用的文件操作方法,可以帮助 Java 开发者快速完成文件相关的操作任务。

FileUtil 类包含以下几类操作工具:

  • 文件操作:包括文件目录的新建、删除、复制、移动、改名等

  • 文件判断:判断文件或目录是否非空,是否为目录,是否为文件等等。

  • 绝对路径:针对 ClassPath 中的文件转换为绝对路径文件。

  • 文件名:主文件名,扩展名的获取

  • 读操作:包括 getReaderreadXXX 操作

  • 写操作:包括 getWriterwriteXXX 操作

Hutool FileUtils 相对于 Apachei FileUtils 增加了一些特性,例如支持文件NIO 操作、文件比较、文件分割合并等,特别是对大文件操作优化,所以在大文件操作上,使用 Hutool FileUtils 会更有优势。

Path 类

Path 类 在 Java 7 被引入,是 Java NIO 中用于处理文件和目录的路径的类,它提供了一组方法用于处理和操作路径字符串。旨在替代传统的java.io.File 类。

使用 Path 类,可以轻松地创建、操作和检查文件和目录的路径,可以将字符串和 URI 转换为 Path 对象。

常用方法

  1. resolve(String other): 根据指定的字符串构建一个新的 Path 对象,作为当前路径的子路径。

  2. resolve(Path other): 根据指定的 Path 对象构建一个新的 Path 对象,作为当前路径的子路径。

  3. getParent(): 获取当前路径的父路径,返回一个包含父路径的 Path 对象,如果没有父路径则返回 null。

  4. getRoot(): 获取当前路径的根路径,返回一个包含根路径的 Path 对象,如果当前路径没有根,则返回 null。

  5. getFileName(): 获取当前路径的文件或目录名,返回一个包含文件或目录名的 Path 对象。

  6. getCurrentDirectory():获取当前工作目录的Path对象。

  7. normalize(): 返回一个去除冗余标识符(如".“和”…")的规范化路径的 Path 对象。

  8. toAbsolutePath(): 返回当前路径的绝对路径,即包含完整路径信息的 Path 对象。

  9. toFile(): 将 Path 对象转换为 File 对象。

  10. toString(): 返回表示当前路径的字符串。

  11. path.relativize(Path path2):获取两个路径之间的相对路径。尝试将一个路径相对于另一个路径解析为相对路径,以便可以从一个路径转换为另一个路径,而不需要指定绝对路径。

    如果 path1path2 没有公共的父路径,则 relativize() 方法将抛出 IllegalArgumentException

  12. isAbsolute():判断Path对象是否为绝对路径。

Paths 类

Paths 是 Java NIO 中的一个实用工具类,用于创建和操作 Path 对象。它提供了一组静态方法,用于获取表示文件或目录的 Path 对象,以及在 Path 对象之间执行操作。

  1. get(String first, String... more): 根据指定的路径字符串创建一个 Path 对象。

  2. get(URI uri): 根据指定的 URI 创建一个 Path 对象。

  3. getCurrentDirectory(): 获取当前工作目录的 Path 对象。

  4. getFileSystem(): 获取默认文件系统的文件系统对象。

  5. getFileSystem(URI uri): 根据指定 URI 获取文件系统的文件系统对象。

Files 类

Files 类在 Java 7 被引入,位于 java.nio.file 包中,提供了大量静态方法,用于处理文件系统中的文件和目录。旨在提供更简单、更强大和更灵活的文件操作功能,相比于传统的 java.io.File 类,Files 类在处理文件和目录时更加方便和便捷。

Path filePath = Paths.get("path/file.txt");
Files.createFile(filePath);

常用方法

Files 类提供了一组方法,用于创建、删除、复制、移动、重命名、读取、写入等常见的文件操作:

  1. createDirectories(Path dir, FileAttribute<?>... attrs): 根据指定的路径创建所有缺失的目录,包括父目录。

  2. createFile(Path path, FileAttribute<?>... attrs): 在指定路径创建一个新文件。

  3. delete(Path path): 删除指定路径的文件或目录。如果是目录,需要确保目录是空的才能删除。

  4. move(Path source, Path target, CopyOption... options): 将指定的源文件或目录移动到目标位置。

  5. copy(Path source, Path target, CopyOption... options): 将指定的源文件或目录复制到目标位置。

  6. readAllBytes(Path path): 读取指定路径的所有字节,并将其作为一个byte数组返回。

  7. readAllLines(Path path, Charset cs):读取文件的所有行到一个字符串列表。

  8. readString(Path path, Charset cs): 读取指定路径的所有字符,并将其作为一个字符串返回。

  9. write(Path path, byte[] bytes, OpenOption... options): 将指定的字节写入到指定的文件中。

  10. writeString(Path path, CharSequence charSequence, OpenOption... options): 将指定的字符串写入到指定的文件中。

  11. exists(Path path, LinkOption... options):检查指定路径的文件是否存在

  12. readAttributes():读取指定文件或目录的文件属性。它接受两个参数:文件路径和要读取的属性类型。返回值的类型取决于要读取的属性类型,通常是属性的集合。

    • path:要读取属性的文件或目录的路径 Path 对象。
    • type:要读取属性的类型。可以是标准的文件系统属性类型,例如 BasicFileAttributesPosixFileAttributesDosFileAttributes。也可以是特定于操作系统的属性类型,例如 UserDefinedFileAttributeView
  13. newBufferedReader(Path path, Charset cs)newBufferedWriter(Path path, Charset cs, OpenOption... options):创建 BufferedReader 和 BufferedWriter 对象以读取和写入文件。

  14. walkFileTree(Path source, FileVisitor visitor):提供一个起始路径(起始目录)和一个实现了 [[#FileVisitor]] 接口的对象。递归地访问目录结构中的所有文件和目录,并允许对这些文件和目录执行自定义操作

FIileAttribute

FileAttribute 是用于在创建文件或目录时指定属性的泛型接口。它是 Java NIO 中的一个概念,并且在操作文件时经常与 Files 类的相关方法一起使用,用于处理各种不同类型的属性。

FileAttribute 接口定义了一个方法 name(),用于获取该属性的名称。具体的文件属性是通过不同的实现类来表示的。在Java中,主要有以下几种实现类:

  1. PosixFilePermissions: 用于指定 POSIX 文件权限(如读、写和执行)的属性。

  2. DosFileAttributeView: 用于指定 DOS/Windows 文件属性(如只读、隐藏和存档)的属性。

  3. BasicFileAttributeView: 用于指定基本的文件属性(如创建时间、修改时间和文件大小)的属性。

PosixFileAttributes

PosixFileAttributes 接口是 Java NIO 中的一个接口,用于访问具有 POSIX 文件系统(Portable Operating System Interface,定义了许多与文件系统相关的操作,包括文件和目录的创建、删除、读取和修改。)(如 Linux 和 macOS)属性的文件的属性。

通过它,可以查询和获取文件的元数据信息,例如所有者、组、权限等。

Path filePath = Paths.get("path/to/file.txt");
PosixFileAttributes attribute = Files.readAttribute(filePath, PosixFileAttributes.class);
常用方法

可以通过 PosixFileAttributes 接口获取有关文件的信息:

  • owner():获取文件的所有者。

  • group():获取文件的组。

  • permissions():获取文件的权限。

  • creationTime():获取文件的创建时间。

  • lastModifiedTime():获取文件的最后修改时间。

  • lastAccessTime():获取文件的最后访问时间。

PosixFilePermission

PosixFilePermission 是 Java NIO 中的一个枚举类型,用于表示 POSIX 文件系统中的文件权限。

POSIX(Portable Operating System Interface for UNIX)是一种用于 UNIX-like 操作系统的标准接口规范,定义了文件的权限控制和访问方式。

PosixFilePermission 枚举类型包括以下值:

  • OWNER_READ:所有者读取权限
  • OWNER_WRITE:所有者写入权限
  • OWNER_EXECUTE:所有者执行权限
  • GROUP_READ:组读取权限
  • GROUP_WRITE:组写入权限
  • GROUP_EXECUTE:组执行权限
  • OTHERS_READ:其他用户读取权限
  • OTHERS_WRITE:其他用户写入权限
  • OTHERS_EXECUTE:其他用户执行权限

在文件系统中,使用 3 个数字来表示文件的权限。

例如,权限 rwxr-x--- 表示所有者具有读取、写入和执行权限,组具有读取和执行权限,其他用户没有权限。

这等效于权限值 750(只考虑 POSIX 文件系统)。可以使用 PosixFilePermission 枚举类型将这些权限表示为代码:

Set<PosixFilePermission> filePermissions = EnumSet.of(
    OWNER_READ, OWNER_WRITE, OWNER_EXECUTE,
    GROUP_READ, GROUP_EXECUTE,
    OTHERS_READ
);

在 Java NIO 中,可以使用 PosixFilePermission 枚举类型和 Files.setPosixFilePermissions() 方法来修改文件的权限:

Path filePath = Paths.get("path/to/file.txt");
Set<PosixFilePermission> newPermissions = EnumSet.of(
    OWNER_READ, OWNER_WRITE,
    GROUP_READ, OTHERS_READ
);
try {
    Files.setPosixFilePermissions(filePath, newPermissions);
} catch (IOException e) {
    e.printStackTrace();
}

PosixFilePermission 只适用于 POSIX 文件系统,在非 POSIX 文件系统上可能会抛出 UnsupportedOperationException 异常。

BasicFileAttributeView

BasicFileAttributeView 是 Java NIO 中的一个接口,用于访问文件的基本属性。

常用方法

以下是一些常用的方法,可以通过 BasicFileAttributeView 获取和设置文件的属性信息:

  • readAttributes():获取文件的属性集合。

  • lastModifiedTime():获取或设置文件的最后修改时间。

  • lastAccessTime():获取或设置文件的最后访问时间。

  • creationTime():获取或设置文件的创建时间。

  • size():获取文件的大小。

DosFileAttributeView

DosFileAttributeView 是 Java NIO 中的一个接口,继承自 BasicFileAttributeView 接口,用于访问具有 DOS/Windows 文件系统属性的文件的属性。

Path filePath = Paths.get("path/to/file.txt");
DosFileAttributes attribute = Files.readAttribute(filePath, DosFileAttributes.class);
常用方法

以下是一些常用的方法,可以通过 DosFileAttributeView 接口获取和设置文件的属性信息:

  • readAttributes():获取文件的属性集合。

  • isArchive():检查文件是否设置了存档属性。

  • isHidden():检查文件是否设置了隐藏属性。

  • isReadOnly():检查文件是否设置为只读属性。

  • setArchive():设置文件的存档属性。

  • setHidden():设置文件的隐藏属性。

  • setReadOnly():设置文件的只读属性。

CopyOption

CopyOption 是 Java NIO 中的一个接口,用于指定在复制文件或目录时的选项。CopyOption 接口是一个标记接口,其具体实现类可以用于在复制操作中提供一些自定义选项。

Java NIO 提供了两个实现了 CopyOption 接口的具体类:

  1. StandardCopyOption:表示一些标准的复制选项。
  2. LinkOption:表示对链接文件的处理选项。
StandardCopyOption
  • REPLACE_EXISTING:如果目标文件或目录已存在,该选项会使 Files.copy() 方法替换目标文件。

    如果不指定此选项,Files.copy() 方法在目标文件已存在时将抛出 FileAlreadyExistsException

  • COPY_ATTRIBUTES:复制文件或目录的属性(比如文件权限、文件时间戳等)。

  • ATOMIC_MOVE:在支持的文件系统上,以原子方式将文件移动到目标位置。

LinkOption

LinkOption 是一个枚举类,它定义了如何处理文件系统链接的选项,位于 java.nio.file 包中。

LinkOption 主要在与文件或目录的路径操作相关的方法中使用,以控制这些方法如何处理符号链接

符号链接是一种特殊类型的文件,它在 Unix 和类 Unix 系统(如 Linux 和 macOS)上很常见。在 Windows 上,类似的概念被称为快捷方式。

  • NOFOLLOW_LINKS:对于符号链接文件,不跟踪它所指向的符号链接文件。

  • FOLLOW_LINKS:表示跟踪符号链接。如果在文件操作中遇到符号链接,将会解析链接指向的实际文件,并对实际文件进行操作。

默认情况下,Java NIO 会自动跟踪符号链接。

OpenOption

OpenOption 是 Java NIO 中的一个接口,用于指定在打开文件时的选项。OpenOption 接口是一个标记接口,其具体实现类可以用于在文件打开操作中提供一些自定义选项。

它提供了在使用 Files.newByteChannel()Files.newInputStream()Files.newOutputStream()AsynchronousFileChannel.open()FileChannel.open() 方法时定制行为的选项

Java NIO 提供了一些实现了 OpenOption 接口的具体类,常用的包括:

  1. StandardOpenOption:表示一些标准的打开选项。

  2. LinkOption:表示对链接文件的处理选项。

StandardOpenOption
  • READ:以读取方式打开文件。

  • WRITE:以写入方式打开文件。

  • APPEND:追加方式打开文件,如果文件不存在则创建新文件。

  • CREATE:如果文件不存在则创建新文件。

  • CREATE_NEW:创建新文件,如果文件已存在则抛出异常 FileAlreadyExistsException

  • TRUNCATE_EXISTING:在写入文件之前,截断文件的内容,使其长度为0,仅适用于 WRITE 或 APPEND 模式。。

  • DELETE_ON_CLOSE:在关闭通道时删除文件。

  • SPARSE:提示文件系统创建一个稀疏文件。

  • SYNC:要求每次更新文件的内容或元数据时都进行同步。

  • DSYNC:要求每次更新文件内容时都进行同步。

这些选项可以用于在打开文件时,指定文件的打开模式,例如只读、写入、追加等。

LinkOption
  • NOFOLLOW_LINKS:对于符号链接文件,不跟踪它所指向的符号链接文件。

  • FOLLOW_LINKS:表示跟踪符号链接。如果在文件操作中遇到符号链接,将会解析链接指向的实际文件,并对实际文件进行操作。

默认情况下,Java NIO 会自动跟踪符号链接。

FileVisitor

FileVisitor 是 Java 中的接口,它用于遍历文件和目录树,并对它们进行操作。FileVisitor 接口定义了四个方法:

  1. preVisitDirectory(Path dir, BasicFileAttributes attrs): 在访问目录之前调用该方法。

  2. visitFile(Path file, BasicFileAttributes attrs): 针对每个文件调用该方法。

  3. visitFileFailed(Path file, IOException exc): 在文件访问失败时调用该方法。

  4. postVisitDirectory(Path dir, IOException exc): 在访问目录之后调用该方法。

当需要遍历目录和文件树时,可以实现 FileVisitor 接口并重写上述方法,然后使用 Files.walkFileTree() 方法启动遍历操作。通过在这些方法中编写特定的逻辑,可以对文件和目录进行特定的操作,例如复制、删除、搜索等。

这个接口的主要作用是提供了一种灵活的方式来管理文件和目录的遍历,并根据具体需求来执行操作。

SimpleFileVisitior

SimpleFileVisitor 是 Java 标准库提供的一个类,它实现了 FileVisitor 接口,提供了默认的文件访问方式。

SimpleFileVisitor 是一个抽象类,它包含了针对文件和目录遍历时各种访问操作的实现。在实际使用时,我们可以通过继承 SimpleFileVisitor 并重写相应方法来定制自己的访问操作。

例如,我们可以实现以下方法:

  • preVisitDirectory(Path dir, BasicFileAttributes attrs):在访问子目录之前被调用。

  • visitFile(Path file, BasicFileAttributes attrs):在访问文件时被调用。

  • visitFileFailed(Path file, IOException exc):在访问文件时发生异常时调用,例如权限不足、文件被锁定等。

  • postVisitDirectory(Path dir, IOException exc):在访问子目录之后被调用。

以上方法都返回 FileVisitResult 枚举类型的实例,用于指示是否跳过当前目录、继续遍历、或者终止遍历。

FileVisitResult

FileVisitorResult 枚举类是 Java 中的一个枚举类,用于表示 FileVisitor 接口中的访问结果。该枚举类定义了四个常量:

  1. CONTINUE:表示继续访问当前文件或目录。
  2. TERMINATE:表示终止遍历,不再访问其他文件或目录。
  3. SKIP_SIBLINGS:跳过兄弟节点,然后继续
  4. SKIP_SUBTREE:表示跳过当前目录及其子目录的访问,继续访问同级别的其他文件或目录。

通过在实现 FileVisitor 接口的类中返回适当的 FileVisitorResult 值,可以控制文件或目录遍历的行为。根据访问的需求,可以决定是继续遍历、终止遍历还是跳过子目录的访问。

示例

实现一个 FileVisitor:

private static class MyFileVisitor extends SimpleFileVisitor<Path> {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            System.out.println("准备访问目录: " + dir);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            System.out.println("正在访问目录: " + dir);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            System.out.println("访问文件: " + file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            System.err.println("访问文件失败: " + file);
            return FileVisitResult.CONTINUE;
        }
    }

在这个示例中,我们创建了一个名为 MyFileVisitor 的自定义 FileVisitor 类,它扩展了 SimpleFileVisitor 类。SimpleFileVisitor 是 FileVisitor 接口的一个实现,它提供了一些默认的行为。

我们可以覆盖 SimpleFileVisitor 中的方法以实现自己的逻辑。在这个例子中,我们只是打印出了访问的文件和目录。然后,我们使用 Files.walkFileTree 方法遍历文件树。这个方法会遍历整个目录结构,并调用 MyFileVisitor 中的相应方法。

walkFileTree 搜索文件

walkFileTree() 方法还可以用于搜索文件,下面这个例子扩展了 SimpleFileVisitor 并覆盖 visitFile() 方法来查找一个名为 test.txt 的文件:

import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class FileSearchVisitor extends SimpleFileVisitor<Path> {
    private Path foundFile;

    // 构造函数
    public FileSearchVisitor() {
        foundFile = null;
    }

    // 检查文件是否匹配
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (file.getFileName().toString().equals("test.txt")) {
            System.out.println("Found the file: " + file);
            foundFile = file;
            // 返回TERMINATE以停止遍历
            return FileVisitResult.TERMINATE;
        }
        // 继续遍历
        return FileVisitResult.CONTINUE;
    }

    // 获取找到的文件
    public Path getFoundFile() {
        return foundFile;
    }

    public static void main(String[] args) throws IOException {
        Path startDir = Paths.get("/path/to/search/directory");

        FileSearchVisitor visitor = new FileSearchVisitor();
        Files.walkFileTree(startDir, visitor);

        if (visitor.getFoundFile() != null) {
            System.out.println("The file 'test.txt' was found at: " + visitor.getFoundFile());
        } else {
            System.out.println("The file 'test.txt' was not found in the directory tree.");
        }
    }
}

代码解释:

  1. 定义 FileSearchVisitor

    • 继承 SimpleFileVisitor<Path>FileSearchVisitor 类继承自 SimpleFileVisitor<Path>,这是一个抽象类,它实现了 FileVisitor<Path> 接口,并提供了默认的方法实现。

    • 构造函数:初始化 foundFilenull,表示还没有找到目标文件。

    • visitFile() 方法:覆盖此方法来处理文件。如果文件名匹配,则打印消息并设置 foundFile 为当前文件路径,并返回 FileVisitResult.TERMINATE 以停止遍历。

    • getFoundFile() 方法:提供一个方法来获取找到的文件路径。

  2. 主方法 (main)

    • 定义起始目录startDir 变量指向要开始搜索的目录。

    • 创建 FileSearchVisitor 实例:创建 FileSearchVisitor 对象 visitor

    • 调用 walkFileTree() 方法:使用 Files.walkFileTree() 方法遍历目录树,并传递 visitor 对象作为参数。

    • 检查结果:根据 visitor.getFoundFile() 的值来判断是否找到了目标文件,并打印相应的消息。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值