我正在参与「启航计划」

这是 android 文件操作的第一篇,之所以从 Java 开始,是由于这样能从前到后彻底弄了解文件相关的操作。

环境阐明:

  • 我学习以 JDK8 为主,之所以选择 8 ,是由于只需 8 有教程,估量 File 相关的 API ,从 8 到 18 都是没有变的,先找到 File 相关的 API;
  • 我的示例都是跑在 JDK18 基础上;
  • 运转环境是 MacOS 13.3.1 (a) (22E772610a);
  • 编辑器为: IntelliJ IDEA 2023.1.2 (Community Edition) ;
  • 写于 2023-6-11 。

其他阐明:

  • 文件夹和目录同一个意义;
  • Path 和途径同一意义。
  1. 类 API

展现所有 File 类相关的办法和特点,也便是文档中给出,详细检查文档: JDK File 。翻译是运用谷歌翻译的成果,读得懂英语的直接看英文,读不了解的看我的了解;翻译仅仅辅佐,那些看得懂英语,但又不是彻底看得懂的人参阅。

1.1 特点

特点称号 类/目标特点 官方描绘和翻译 我的了解
pathSeparator static The system-dependent path-separator character, represented as a string for convenience.为便利起见,表明为字符串的体系相关途径分隔符 途径与途径之间的分隔符,比方两个文件途径:/usr/local/mongodb/bin:/usr/local/mysql/bin。在 Unix 中是 “ : ”,在 Window 中则是 “ ; ”。
pathSeparatorChar static The system-dependent path-separator character.依赖于体系的途径分隔符 跟上面的同一个意义,仅仅上面的回来 String ,这个回来的是 Char 。
separator static The system-dependent default name-separator character, represented as a string for convenience.为便利起见,体系相关的默许称号分隔符表明为字符串 途径中的分隔符,比方 /usr/local/mongodb/bin 中的 / 便是 separator 。在 Unix 中是 / ,在 Window 中则是 “ 。
separatorChar static The system-dependent default name-separator character.体系相关的默许称号分隔符 跟上面相同的意义,上面回来的是 String ,这个回来 Char

1.2 结构函数

结构函数 官方描绘和翻译 我的了解
File(File parent, String child) Creates a new File instance from a parent abstract pathname and a child pathname string.从父笼统途径名和子途径姓名符串创立新文件实例。 拿着第一个参数的 path 与第二个参数组合成一个新的 path ;假设第一个参数传入为 null ,那么就跟**File(String** pathname) 结构函数相同。
File(String pathname) Creates a new File instance by converting the given pathname string into an abstract pathname.通过将给定的途径姓名符串转换为笼统途径名来创立一个新的文件实例。 运用参数构建一个文件目标,自身仅仅保存 path 参数,其他不做任何操作,包括对参数的有效性校验也没有;可是不能传入 null ,会直接抛出空指针反常。
File(String parent, String child) Creates a new File instance from a parent pathname string and a child pathname string.从父途径姓名符串和子途径姓名符串创立新文件实例。 同第一个结构函数,差别在于第一个结构函数需求取 File 目标下的 path 特点,而这个直接运用;相同传入为 null 的话就跟第二个结构函数相同。
File(URI uri) Creates a new File instance by converting the given file: URI into an abstract pathname.通过将给定文件 uri 转换为笼统途径名来创立新文件实例。 跟第二个结构函数差不多意义,差异在于这个需求取出 URI 目标中的相关特点。

1.3 办法

办法声明 官方描绘和翻译 我的了解
boolean canExecute() Tests whether the application can execute the file denoted by this abstract pathname.测验应用程序是否能够履行此笼统途径名表明的文件。 回来当时途径中的文件是否为可履行文件。当这个文件、文件夹自身还不存在,直接回来 false ;文件特点,假设有可履行权限并有权限的状况下,回来 true ,不然回来false ;自身不论履行成果是否真的牢靠。
boolean canRead() Tests whether the application can read the file denoted by this abstract pathname.测验应用程序是否能够读取此笼统途径名表明的文件。 判别文件是否有可读权限,其他同上。
boolean canWrite() Tests whether the application can modify the file denoted by this abstract pathname.测验应用程序是否能够修正此笼统途径名表明的文件。 判别文件是否有可写权限,其他同上。
int compareTo(File pathname) Compares two abstract pathnames lexicographically.按字典次序比较两个笼统途径名。 跟 String 的 compareTo 类似,详细看下面的示例。
boolean createNewFile() Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.当且仅当具有此称号的文件尚不存在时,以原子办法创立一个以此笼统途径名命名的新空文件。 创立新文件,创立的文件原本不存在,所创立文件的所属文件夹存在而且有权限才干成功。
static File ****createTempFile(String prefix,String suffix) Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name.运用给定的前缀和后缀在默许临时文件目录中创立一个空文件以生成其称号。 创立包括指定文件前缀和后缀的临时文件。
static File ****createTempFile(String prefix,String suffix,File directory) Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name.运用给定的前缀和后缀字符串在指定目录中创立一个新的空文件以生成其称号。 在给出的文件夹中创立包括指定文件前缀和后缀的文件。概况见 2.3.26
boolean delete() Deletes the file or directory denoted by this abstract pathname.删去此笼统途径名表明的文件或目录。 删去文件或文件夹。需求文件或文件夹的所属文件夹有权限。
void deleteOnExit() Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.恳求在虚拟机停止时删去此笼统途径名表明的文件或目录。 删去文件或文件夹,跟 delete 相同,只不过这个是在虚拟机停止才会去删去,而不是立马删去。
boolean equals(Object obj) Tests this abstract pathname for equality with the given object.测验此笼统途径名是否与给定目标持平。 参数假设不是 File 目标直接回来 false ,不然跟 int compareTo(File pathname) 相同。
boolean exists() Tests whether the file or directory denoted by this abstract pathname exists.测验此笼统途径名表明的文件或目录是否存在。 判别文件或文件夹是否存在。
File ****getAbsoluteFile() Returns the absolute form of this abstract pathname.回来此笼统途径名的必定方式。 得到必定途径的 File 目标,便是拿 File 目标的必定途径来新建一个新的 File 目标。概况见 2.3.15
String ****getAbsolutePath() Returns the absolute pathname string of this abstract pathname.回来此笼统途径名的必定途径姓名符串。 获取 File 的必定途径,假设自身便是直接回来。
File ****getCanonicalFile() Returns the canonical form of this abstract pathname.回来此笼统途径名的标准方式。 用文件的标准途径创立新的 File 目标,至于什么是标准途径看 String ****getCanonicalPath() 函数;这儿的标准是我运用翻译软件得到的成果,但意义是没问题的。
String ****getCanonicalPath() Returns the canonical pathname string of this abstract pathname.回来此笼统途径名的标准途径姓名符串。 获取标准途径,也便是假设文件/文件夹里边带有 ... 这样的存在,那么这些会整合到途径中,显现实在的途径;假设 File 目标的 path 是一个软链接,那么会显现文件实在的途径。 概况见 2.3.16
long getFreeSpace() Returns the number of unallocated bytes in the partition named by this abstract path name.回来由此笼统途径名命名的分区中未分配的字节数。 我没有弄懂,网上的意义是:办法回来此笼统途径名的分区中的未分配的字节数。 分配的字节数回来的不是一个确保。 未分配的字节数或许是这个调用和不准确的任何外部I/ O操作后当即是准确的。信息来源于:getFreeSpace
String ****getName() Returns the name of the file or directory denoted by this abstract pathname.回来此笼统途径名表明的文件或目录的称号。 获取途径中的最终一个称号,假设:test/a/b/c ,那么得到的是 c ;假设是 ../ ,那么得到的是 .. 。概况看 2.3.14
String ****getParent() Returns the pathname string of this abstract pathname’s parent, or null if this pathname does not name a parent directory.回来此笼统途径名父目录的途径姓名符串,假设此途径名未指定父目录,则回来 null 。 回来当时文件或文件夹的父级文件夹。主要是看 path 中是否含有 / ,假设有,去掉最终一个 / 后的内容便是父级文件途径。跟创立文件时的 pathname 有直接关系,假设是相对途径也只会回来相对途径。
File ****getParentFile() Returns the abstract pathname of this abstract pathname’s parent, or null if this pathname does not name a parent directory.回来此笼统途径名父目录的笼统途径名;假设此途径名未指定父目录,则回来 null 。 跟上一个类似,只不过这个会创立 File 目标。
String ****getPath() Converts this abstract pathname into a pathname string.将此笼统途径名转换为途径姓名符串。 获取 Filepath ,便是创立目标时传入的参数,详细看 2.3.12 示例。
long getTotalSpace() Returns the size of the partition named by this abstract pathname.回来由此笼统途径名命名的分区的巨细。 不是很了解,也不知道有啥用,网上的解说:回来此笼统途径名的分区的巨细。信息来源于:getTotalSpace 。
long getUsableSpace() Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname.回来此笼统途径名命名的分区上此虚拟机可用的字节数。 同上。网上的解说:回来可用字节数,这个虚拟机上的分区是此笼统姓名。这种办法通常会提供多少新的数据实际上能够写成这种办法检查写权限和其他操作体系的约束,以更准确的估量。信息来源于: getUsableSpace 。
int hashCode() Computes a hash code for this abstract pathname.核算此笼统途径名的哈希码。 也便是 hashcode 值。至于为啥需求用到这个,由于 java 中都是有这个的,所以今后会出相关得到学习记载。
boolean isAbsolute() Tests whether this abstract pathname is absolute.测验这个笼统途径名是否是必定的。 File 目标的 path 是否为必定途径。也便是回来 File 目标初始化的时分是否是必定途径。
boolean isDirectory() Tests whether the file denoted by this abstract pathname is a directory.测验此笼统途径名表明的文件是否为目录。 判别 path 是不是文件夹。
boolean isFile() Tests whether the file denoted by this abstract pathname is a normal file.测验此笼统途径名表明的文件是否为一般文件。 判别 path 是不是文件。
boolean isHidden() Tests whether the file named by this abstract pathname is a hidden file.测验以此笼统途径名命名的文件是否为躲藏文件。 判别途径是不是处于躲藏的状况。也便是在访达中看不到的文件或文件夹。
long lastModified() Returns the time that the file denoted by this abstract pathname was last modified.回来最终修正此笼统途径名表明的文件的时刻。 回来文件或文件夹最近一次修正的时刻,假设文件或文件夹不存在那么回来 0
long length() Returns the length of the file denoted by this abstract pathname.回来此笼统途径名表明的文件的长度。 假设是文件回来文件中的内容长度(字节),文件夹回来的值未指定,概况见: 2.3.32
String [] list() Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname.回来一个字符串数组,命名此笼统途径名表明的目录中的文件和目录。 回来文件夹中的文件或文件夹。
String [] list(FilenameFilter filter) Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.回来一个字符串数组,命名此笼统途径名表明的目录中满意指定过滤器的文件和目录。 按指定过滤器过滤后的文件或文件夹。
File [] listFiles() Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.回来笼统途径名数组,表明此笼统途径名表明的目录中的文件。 String [] list() 类似,不同在于这个会回来 File 目标的数组。
File [] listFiles(FileFilter filter) Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.回来一个笼统途径名数组,表明此笼统途径名表明的目录中满意指定过滤器的文件和目录。 按指定过滤器过滤文件或文件夹,回来 false 的会被过滤掉,然后拿着过滤得到的文件或文件夹创立 File 目标回来。这儿跟 FilenameFilter 不同的是,这个回调是 path (通过 getPath() 得到的)所对应的 FIle 目标,而 FilenameFilter 有两个参数,第一个是调用者,第二个是称号(通过 getName 得到的那个)。概况看 2.3.35
File [] listFiles(FilenameFilter filter) Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.回来一个笼统途径名数组,表明此笼统途径名表明的目录中满意指定过滤器的文件和目录。 依据 FilenameFilter 的办法过滤文件夹下的子级(直接),然后再依据这些子级创立 File 目标。
static File [] listRoots() List the available filesystem roots.列出可用的文件体系根目录。 也便是回来文件体系根目录,比方我的电脑 MAC ,回来的是 [/] ;而 Windows 则有多个,比方 C 盘; D 盘等等。
boolean mkdir() Creates the directory named by this abstract pathname.创立以此笼统途径名命名的目录。 依据 path 创立文件夹,假设存在多级目录不存在,那么创立失利;假设所创立文件所属文件夹并没有权限,那么创立失利。
boolean mkdirs() Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories.创立以此笼统途径名命名的目录,包括任何必要但不存在的父目录。 跟上面相同,不同的是能够创立多级文件夹,也便是 a/b/c/d 中,即便只需 a 文件夹存在,那么也能将其他文件夹创立成功。
boolean renameTo(File dest) Renames the file denoted by this abstract pathname.重命名此笼统途径名表明的文件。 对文件进行重命名。没有权限的文件夹不能操作;假设文件所属的文件夹有权限,那么此文件有没有权限都是能够操作的。重命名只能在当时的文件夹下,不能像 mv 指令那样运用。不存在的文件毫不犹豫的失利。
boolean setExecutable(boolean executable) A convenience method to set the owner’s execute permission for this abstract pathname.设置所有者对此笼统途径名履行权限的快捷办法。 文件所有者修正文件的可履行权限,只能修正 [所有者][群组][其他用户] 中的 [所有者] 可履行权限。
boolean setExecutable(boolean executable,boolean ownerOnly) Sets the owner’s or everybody’s execute permission for this abstract pathname.设置所有者或每个人对此笼统途径名的履行权限。 现在我电脑测验的成果跟 boolean setExecutable(boolean executable) 相同。
boolean setLastModified(long time) Sets the last-modified time of the file or directory named by this abstract pathname.设置以此笼统途径名命名的文件或目录的最终修正时刻。 修正文件的最近一次修正时刻。
boolean setReadable(boolean readable) A convenience method to set the owner’s read permission for this abstract pathname.为这个笼统途径名设置所有者读取权限的快捷办法。 文件所有者修正文件的可履行权限,只能修正 [所有者][群组][其他用户] 中的 [所有者] 可读权限。
boolean setReadable(boolean readable,boolean ownerOnly) Sets the owner’s or everybody’s read permission for this abstract pathname.设置所有者或每个人对此笼统途径名的读取权限。 现在我电脑测验的成果跟 boolean setReadable(boolean readable) 相同。
boolean setReadOnly() Marks the file or directory named by this abstract pathname so that only read operations are allowed.标记由此笼统途径名命名的文件或目录,以便只允许读取操作。 设置文件为可读,也便是将文件的可写权限删去,其他权限不动。详细看 2.3.10
boolean setWritable(boolean writable) A convenience method to set the owner’s write permission for this abstract pathname.为这个笼统途径名设置所有者写权限的快捷办法。 文件所有者修正文件的可履行权限,只能修正 [所有者][群组][其他用户] 中的 [所有者] 可写权限。
boolean setWritable(boolean writable,boolean ownerOnly) Sets the owner’s or everybody’s write permission for this abstract pathname.设置所有者或每个人对此笼统途径名的写权限。 现在我电脑测验的成果跟 boolean setWritable(boolean writable) 相同。
Path ****toPath() Returns a java.nio.file.Path object constructed from the this abstract path.回来从这个笼统途径结构的 java.nio.file.Path 文件途径目标。 转换成 Path 目标。
String ****toString() Returns the pathname string of this abstract pathname.回来此笼统途径名的途径姓名符串。 getPath 相同。
URI ****toURI() Constructs a file: URI that represents this abstract pathname.结构表明此笼统途径名的文件 URI 。 转成成 URI 目标。
  1. 代码示例展现

这儿将上面的 API 都进行代码展现,并给出输出成果,然后在得出结论和相关的用处阐明。

2.1 特点示例

2.1.1 pathSeparator

// 源码展现
public static final String pathSeparator = String.valueOf(pathSeparatorChar);
// 示例展现
System.out.println(File.pathSeparator); // Unix :    WIndow ;

2.1.2 pathSeparatorChar

// 源码展现
public static final char pathSeparatorChar = fs.getPathSeparator();
// 示例展现
System.out.println(File.pathSeparatorChar); // Unix :    WIndow ;

2.1.3 separator

// 源码展现
public static final String separator = String.valueOf(separatorChar);
// 示例展现
System.out.println(File.separator); // Unix /    WIndow \

2.1.4 separatorChar

// 源码展现
public static final char separatorChar = fs.getSeparator();
// 示例展现
System.out.println(File.separatorChar); // Unix /    WIndow \

2.2 结构函数示例

结构函数都仅仅将传入的参数保存为 pathprefixLength 这两个私有特点,所以只需你是字符串都是不会报错的,其途径是否真的有效,还得看调用详细的办法才干清楚;不然预先判别你传入途径的正确性,在 Java 层面即便在详细的操作也不会判别其正确性,其底层是调用的 native 代码,只需抛出了 IO 反常才干知道有没有过错。

2.2.1 File(String pathname)

// 通过途径称号创立 File 目标
File file = new File("./"); // 运用相对途径创立 File ,也能够直接传入文件夹称号,就像 test 
File file = new File("test");
File file = new File("/test");

其实只需是契合途径标准的字符串都是能够传入的,只不过内部会判别传入的是相对途径还是必定途径;假设 / 最初就会判别为必定途径,不然相对途径。假设传入的是 null ,那么就会直接抛 NullPointerException 反常。

之所以只需是契合途径的字符串都是能够的,这是由于对文件的详细操作在办法中,初始化只会保存两个局部变量 pathprefixLength ;其间 path 咱们能够直接通过 file.getPath() 来拿到,至于 prefixLength 是内部运用的。

由于要求的字符串,这就意味着只需咱们传入的是字符串就能够,所以你或许会传入 “” ,字符串,这样也是不会报错的,可是空字符串在调用一些办法是不能够的。

也能够传入“ ~ ”这个字符串,可是这也会被作为最一般的字符串,也便是说假设你在此基础上创立文件夹和文件都会得到 ~ 这样的文件或文件夹。

2.2.2 File(String parent, String child)

也便是将这两个途径组合在一起,能够了解为传入的两个参数会变成 parent/child 的方式。

File file = new File("test", "childrenTest");
// 假设打印 getPath 的话,能够得到 test/childrenTest
// 这种状况下,第一个参数能够为 null ,当为空的时分就相当于 2.2.1 结构函数
File file = new File(null, "test");
// 假设打印 getPath 的话,得到的是 test

这两个的取值都是字符串,跟 2.2.1 比起来便是第一个参数能够为空,而第二个参数则跟 2.2.1 彻底相同;假设第一个参数为空字符串,也便是 “” 的状况下会发生什么呢,假设这样做,会把第二个参数看成是必定途径的一部分,也便是假设我这样:

File file = new File("", "childrenTest");
// 此刻打印 getPath 的话,就会得到 /childrenTest

2.2.3 File(File parent, String child)

这个也跟 2.2.2 差不多,只不过多了将 parent File 目标的途径拿到然后再进行拼接。

File file = new File("parentTest");
File fileChild = new File(file, "test");
// 假设打印 fileChild 的 getPath 的话,那么得到的便是 parentTest/test

总体的规则跟 2.2.2 相同,都是多了一步会取 parent File 中的 path 特点。

2.2.4 File(URI uri)

跟 2.2.3 相同也是将 uri 转换成 path

2.3 办法的示例

2.3.1 boolean canExecute()

判别 File 是否是一个可履行文件。

File file = new File("/Applications/Xcode.app");
System.out.println(file.canExecute()); // true

我安装了 Xcode ,所以这儿回来为 true ;下面咱们看看一个一般的文本,也便是 txt 文件,咱们知道这个必定不是,咱们在代码里边看看:

File file = new File("./test.txt");
System.out.println(file.canExecute()); // false

我在项目下新建了一个文件 test.txt ,然后在这儿写入一些文本 “hello world” ,成果履行这个代码,回来了期待的值 false 。下面咱们新建一个 shell 脚本文件,看看代码:

#!/bin/bash
echo "hello world"

这是 shell 脚本,我放在了项目下,文件称号为: test-shell.sh

File file = new File("./test-shell.sh");
System.out.println(file.canExecute()); // false

能够看到成果是 false ,可是我在 idea 里边运转发现是能够的,为啥会这样,接下来我测验去终端中运转:

fileLearn@wujingyue:~$ ./test-shell.sh
# 成果为: zsh: permission denied: ./test-shell.sh

发现呈现了过错。然后我测验运用 sh ./test-shell.sh ,其间 sh 是专门用来履行 shell 脚本的;

fileLearn@wujingyue:~$ sh ./test-shell.sh
# 成果为: hello world

发现是能够的,那问题出在哪里,咱们通过履行 ll 检查一下这个文件的权限:

fileLearn@wujingyue:~$ ll
# 成果: -rw-r--r--@ 1 wujingyue  staff    31B Jun 11 21:43 test-shell.sh

咱们看到并没有可履行权限,咱们测验先给文件增加可履行权限:

fileLearn@wujingyue:~$ chmod 755 ./test-shell.sh
fileLearn@wujingyue:~$ ./test-shell.sh
# 成果: hello world

也便是说 sh 默许在终端是不能够履行的,需求赋予可履行权限才干履行。操作这些今后咱们再履行上面的 Java 代码:

File file = new File("./test-shell.sh");
System.out.println(file.canExecute()); // true

看到这儿有没有觉得这个函数是看文件是不是具有可履行权限来判别的,咱们能够进一步验证,咱们把之前不可的 txt 文件也改一下权限,让其具有可履行的权限:

fileLearn@wujingyue:~$ chmod 755 ./test.txt
fileLearn@wujingyue:~$ ./test.txt
# ./test.txt: line 1: hello: command not found

咱们看到履行呈现了过错,然后这个时分咱们再履行 Java 代码:

File file = new File("./test.txt");
System.out.println(file.canExecute()); // true

果然是咱们想的那样。为了进一步证明,我测验了修正 jpg, zip 等格局,发现依然遵循上面的结论。假设文件不存在,那么这个函数也是会直接回来 false 的。假设不是咱们创立的文件,比方是 root 用户创立的文件或文件夹,那么的得到的成果则为下面的状况:

// 首要运用 root 权限创立文件夹
// sudo mkdir testFolder
// 这儿时分咱们检查文件夹的权限状况
// drwxr-xr-x@ 2 root       staff    64B Jun 12 21:59 testFolder
// 咱们看到都有可履行权限
File file = new File("testFile");
System.out.println(file.canExecute()); // true
// 假设咱们测验修正文件夹的权限,也是让 [所有者][群组][其他用户] 
// 中的其他用户没有可履行权限
// sudo chmod 754 testFolder
// drwxr-xr--@ 2 root       staff    64B Jun 12 21:59 testFolder
System.out.println(file.canExecute()); // true
// 然后咱们再把文件夹的群组权限也修正掉
// sudo chmod 744 testFolder
// drwxr--r--@ 2 root       staff    64B Jun 12 21:59 testFolder
System.out.println(file.canExecute()); // false

能够发现履行的成果,主要看当时用户地点 [所有者权限][群组权限][其他用户权限] 分组中的权限,假设地点分组里边有可履行权限,那么就会回来 true

2.3.2 boolean canRead()

判别文件是否有可读的权限。依据上面的,咱们主要做三种操练,不存在的文件;文件存在可是没有可读权限;文件存在有可读权限。

File file = new File("06.jpg");
System.out.println(file.canRead()); // false

这儿的“06.jpg”文件并不存在,所以不存在的文件直接回来 false

// 我先将我的文件 01.jpg 的权限修正为: 000
// fileLearn@wujingyue:~$ chmod 000 ./01.jpg
// fileLearn@wujingyue:~$ ll
// ----------  1 wujingyue  staff    13K Jun 11 22:20 01.jpg
File file = new File("01.jpg");
System.out.println(file.canRead()); // false

然后咱们再将文件的权限修正成可履行的权限。

// fileLearn@wujingyue:~$ chmod 400 ./01.jpg
// fileLearn@wujingyue:~$ ll
// -r--------@ 1 wujingyue  staff    13K Jun 11 22:20 01.jpg
File file = new File("01.jpg");
System.out.println(file.canRead()); // true

2.3.3 boolean canWrite()

判别文件是否具有可写入的权限。跟上面相同的操练。

// 在上面我现已将文件的可写入权限去掉
File file = new File("01.jpg");
System.out.println(file.canRead()); // false
// fileLearn@wujingyue:~$ chmod 200 ./01.jpg
// fileLearn@wujingyue:~$ ll
// --w-------  1 wujingyue  staff    13K Jun 11 22:20 01.jpg
System.out.println(file.canRead()); // true

2.3.4 boolean setExecutable(boolean executable)

在上面都是通过运用终端命令: chmod 755 ./01.jpg 来给文件赋予权限的,为了便利了解,这儿就通过程序来给文件增加对应的权限。

给文件增加可履行的权限。

File file = new File("01.jpg");
System.out.println(file.canExecute()); // false
file.setExecutable(true);
System.out.println(file.canExecute()); // true

咱们这儿并没有接纳函数的回来值,一般 idea 会提示咱们接纳其回来值,之所以有回来值,主要是能够用来判别此次行为是否收效。下面咱们来看怎样的会导致失利。

File file = new File("05.jpg");
System.out.println(file.canExecute()); // false
file.setExecutable(true);
System.out.println(file.canExecute()); // false

我并没有“05.jpg”这个文件,所以 setExecutable 的成果为 false 。下面我运用 sudo 权限新建一个文件夹 testFolder ,然后通过 sudo chmod 744 testFolder 来改动文件夹的权限,让群组和其他没有可履行的权限,这种状况下,咱们再调用看看状况:

File file = new File("testFolder");
System.out.println(file.canExecute()); // false
System.out.println(file.setExecutable(true)); // false
System.out.println(file.canExecute()); // false

我测验运用 sudo 权限再新建一个一般文本,然后再看看其状况:

// fileLearn@wujingyue:~$ sudo touch testFile
// -rw-r--r--@ 1 root       staff     0B Jun 12 21:27 testFile
File file = new File("testFile");
System.out.println(file.canExecute()); // false
System.out.println(file.setExecutable(true)); // false
System.out.println(file.canExecute()); // false

咱们看到成果都是 false ;由于其他用户创立的文件,其他用户没有修正的权限,也便是可写入的权限;下面咱们运用 sudo 来修正文件权限,让其他用户权限中有可写入的权限。

// fileLearn@wujingyue:~$ chmod 646 testFile
// -rw-r--rw-@ 1 root       staff     0B Jun 12 21:27 testFile
File file = new File("testFile");
System.out.println(file.canExecute()); // false
System.out.println(file.setExecutable(true)); // false
System.out.println(file.canExecute()); // false

能够看到即便具有写入权限,而且咱们这儿跟文件所有者的权限持平,可是非 root 权限用户都是没有权限修正其可履行性的。也便是关于现在来说,其能成功的状况有:

  • 文件存在而且有权限。

不成功的状况有:

  • 文件不存在;
  • 不是文件的所有者都是不能修正的。

这儿要阐明的是,假设仅仅 file.canExecute() 来判别函数的可履行权限,这儿只需履行程序的用户地点分组有可履行权限,都会回来 true ,这跟 file.setExecutable(true) 不同。

2.3.5 boolean setExecutable( boolean executable, boolean ownerOnly)

依据上面的函数 boolean setExecutable(boolean executable) 得出的结论是不是文件的所有者都是不成功的,由于上面的函数其实也是调用的这个函数,只不过后面的 ownerOnly 参数值为 true

这个函数通过我用我的 MAC 电脑测验,发现跟上面的函数相同。

2.3.6 boolean setReadable(boolean readable)

这个跟上面的可履行权是相同的;也便是文件所有者能够对其操作。

2.3.7 boolean setReadable(boolean readable, boolean ownerOnly)

跟 2.3.5 相同,只不过这个是可读权限。

2.3.8 boolean setWritable(boolean writable)

跟 2.3.6 相同,只不过这个是可写入权限。

2.3.9 boolean setWritable(boolean writable, boolean ownerOnly)

跟 2.3.5 相同,只不过这个是可写入权限。

2.3.10 boolean setReadOnly()

文件所有人将文件的权限改成仅可读权限。会将文件的可写入权限删去掉,可读取的权限坚持不变,也便是说假设原本就没有读取的权限,那么履行的成果依然是不可读的权限。可履行权限相同不受影响。

/*
会将文件的可写入权限删去掉,其他权限坚持不变,
也便是这个函数其实修正的写入权限(删去写入权限)
跟上面的 boolean setWritable(boolean writable) 不同
这个会将 [所有者][群组][其他用户] 三种人物
的写入权限都删去掉。
*/
// -rw-rw-rw-@ 1 wujingyue  staff     0B Jun 13 20:59 test
File file = new File("test");
System.out.println(file.setReadOnly());
// -r--r--r--@ 1 wujingyue  staff     0B Jun 13 20:59 test

假设文件自身有所有的 [ 可读可写可履行 ] 权限:

// -rwxrwxrwx@ 1 wujingyue  staff     0B Jun 13 20:59 test
File file = new File("test");
System.out.println(file.setReadOnly());
// -r-xr-xr-x@ 1 wujingyue  staff     0B Jun 13 20:59 test

至于履行失利的状况,跟上面相同。

2.3.11 int compareTo(File pathname)

跟字符串的 compareTo 函数相同;只不过这儿取的是 File 目标 path 特点,而 path 特点是咱们传入的字符串。详细看函数的源代码:

public int compareTo(File pathname) {
    return fs.compare(this, pathname);
}
@Override
public int compare(File f1, File f2) {
    return f1.getPath().compareTo(f2.getPath());
}

这儿的 getPath 是获取文件的途径(详细见 2.3.12 ),而这儿的途径也便是咱们传入的字符串。

File file1 = new File("test1");
File file2 = new File("test1");
System.out.println(file1.getPath()); // test
System.out.println(file2.getPath()); // test
System.out.println(file1.compareTo(file2)); // 0

或许有人觉得是两个文件是否指同一个文件:

File file1 = new File("test1");
File file2 = new File(file1.getAbsolutePath());
System.out.println(file1.getPath()); // test1
System.out.println(file2.getPath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/test1
System.out.println(file1.compareTo(file2)); // 69

这儿的 file1.getAbsolutePath() 是文件 file1 的必定途径,这样两个文件便是指同一个文件。

2.3.12 String ****getPath()

得到文件的途径,这儿指的是创立 File 目标传入的 pathname 参数。

File file1 = new File("test1");
System.out.println(file1.getPath()); // test1
File file1 = new File("/test1/1/2/3");
System.out.println(file1.getPath()); // /test1/1/2/3
File file1 = new File("C:\test\1\2\3\4");
System.out.println(file1.getPath()); // C:\test\1\2\3\4
File file1 = new File("C:\test\1\2\3\4");
File file2 = new File(file1.getAbsolutePath());
System.out.println(file1.getAbsolutePath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/C:\test\1\2\3\4
System.out.println(file2.getPath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/C:\test\1\2\3\4

关于 getAbsolutePath 函数,详细检查 2.3.13

2.3.13 String ****getAbsolutePath()

获取文件的必定位置。

File file1 = new File("test");
System.out.println(file1.getAbsolutePath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/test

假设传入的自身便是必定途径,那么就直接运用咱们传入的:

File file1 = new File("/test/1/2");
System.out.println(file1.getAbsolutePath()); // /test/1/2

或许你觉得我传入的不是实在的途径,的确我的电脑上没有这个途径,可是 File 自身不去做相关校验,原本 File 也不知道其实在目的,比方你传入的途径虽然不存在,可是将来你或许拿着这个地址创立相应的文件夹和文件。

2.3.14 String ****getName()

获取途径的称号,也便是咱们传入的最终一个 / 后的字符串。咱们直接看源码:

public String getName() {
    // 从后往前找分隔符第一次呈现的下标
    int index = path.lastIndexOf(separatorChar);
    if (index < prefixLength) return path.substring(prefixLength);
    //index 到最终的字符串回来
    return path.substring(index + 1);
}

接下来咱们来看例子:

File file1 = new File("test");
System.out.println(file1.getName()); // test
File file1 = new File(".");
System.out.println(file1.getName()); // .
File file1 = new File("../");
System.out.println(file1.getName()); // ..
File file1 = new File("/User/wujingyue/Learn");
System.out.println(file1.getName()); // Learn
File file1 = new File("test/Learn/java/file");
System.out.println(file1.getName()); // file

2.3.15 File ****getAbsoluteFile()

运用文件的必定途径来创立新的 File 目标。这个函数也是看源码能更好的了解:

public File getAbsoluteFile() {
    // 获取当时文件的必定途径
    String absPath = getAbsolutePath();
    if (getClass() != File.class) {
        absPath = fs.normalize(absPath);
    }
    // 运用必定途径新建 File 目标
    return new File(absPath, fs.prefixLength(absPath));
}

下面再看看示例:

File file1 = new File("test/Learn/java/file");
File absoluteFile = file1.getAbsoluteFile();
System.out.println(file1.getPath()); // test/Learn/java/file
System.out.println(file1.getAbsolutePath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/test/Learn/java/file
System.out.println(absoluteFile.getPath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/test/Learn/java/file

2.3.16 String ****getCanonicalPath()

回来此 FIle 的标准途径称号,此称号是必定途径。不论在初始化传入的称号是相对途径还是必定途径,这个的输入都是必定途径。

File file1 = new File("test");
try {
    System.out.println(file1.getCanonicalPath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/test
} catch (IOException e) {
    throw new RuntimeException(e);
}

所谓的标准的途径称号,也便是假设途径中包括像 ... 这样的符号,都会转换成途径:

File file1 = new File(".");
try {
    System.out.println(file1.getCanonicalPath());// /Users/wujingyue/Learns/java/learn-project/fileLearn
    // 假设是 ../../ ,则输出为: /Users/wujingyue/Learns/java
} catch (IOException e) {
    throw new RuntimeException(e);
}

除了上面的,还有文件的软链接会显现文件/目录的实在途径,而不是软链接的途径。

// 先将文件的软链接创立好
// ln -s ~/Downloads/Auto-GPT-0.3.1 ./testlns
File file1 = new File("testlns");
try {
    System.out.println(file1.getCanonicalPath());
    // 输出成果:/Users/wujingyue/Downloads/Auto-GPT-0.3.1
} catch (IOException e) {
    throw new RuntimeException(e);
}

说到软链接,或许会想到硬链接,硬链接不受影响。

2.3.17 File ****getCanonicalFile()

跟上面相同,只不过这个是拿到标准的途径后创立一个 File 目标回来。

File file1 = new File("testlns");
try {
    File file2 = file1.getCanonicalFile();
    System.out.println(file1.getAbsolutePath()); // /Users/wujingyue/Learns/java/learn-project/fileLearn/testlns
    System.out.println(file1.getCanonicalPath()); // /Users/wujingyue/Downloads/Auto-GPT-0.3.1
    System.out.println(file2.getPath()); // /Users/wujingyue/Downloads/Auto-GPT-0.3.1
} catch (IOException e) {
    throw new RuntimeException(e);
}

下面咱们再看看源码,进一步验证咱们的说法:

public File getCanonicalFile() throws IOException {
    // 得到 path 得到标准途径
    String canonPath = getCanonicalPath();
    if (getClass() != File.class) {
        canonPath = fs.normalize(canonPath);
    }
    // 拿着途径创立 File 目标
    return new File(canonPath, fs.prefixLength(canonPath));
}

2.3.18 boolean isAbsolute()

判别 Filepath 是不是必定途径,假设是必定途径就回来 true ,不然回来 false 。在我的电脑上( MAC ),只需途径是 / 最初的会回来 true ,其他的则为 false

File file1 = new File("//");
System.out.println(file1.isAbsolute()); // true
File file1 = new File("/");
System.out.println(file1.isAbsolute()); // true
File file1 = new File("123");
System.out.println(file1.isAbsolute()); // false
File file1 = new File("abc");
System.out.println(file1.isAbsolute()); // false
File file1 = new File("!");
System.out.println(file1.isAbsolute());

2.3.19 boolean isDirectory()

判别 File 是不是文件夹。

// 先检查当时目录的各个文件的状况
// ll
/*
--wx------  1 wujingyue  staff    13K Jun 11 22:20 01.jpg
lrwxr-xr-x@ 1 wujingyue  staff    52B Jun 19 21:03 02.jpg -> /Users/wujingyue/Downloads/飞书20230611-215059.jpg
-rw-r--r--@ 1 wujingyue  staff   423B Jun 11 14:50 fileLearn.iml
drwxr-xr-x@ 2 wujingyue  staff    64B Jun 12 21:15 folder
drwxr-xr-x@ 3 wujingyue  staff    96B Jun 11 15:06 out
-rw-r--r--@ 2 wujingyue  staff    13K Jun 11 21:50 pp.jpg
drwxr-xr-x@ 4 wujingyue  staff   128B Jun 19 20:56 src
-rw-r--r--@ 1 root       staff     0B Jun 13 21:36 test
lrwxr-xr-x@ 1 wujingyue  staff    41B Jun 18 20:51 testlns -> /Users/wujingyue/Downloads/Auto-GPT-0.3.1
*/
// 当是软链接的状况,自身是文件夹
File file1 = new File("testlns");
System.out.println(file1.isDirectory()); // true
// 当自身不存在的途径
File file1 = new File("test11");
System.out.println(file1.isDirectory()); // false
// 当途径是文件的时分
File file1 = new File("test");
System.out.println(file1.isDirectory()); // false
// 自身便是文件夹
File file1 = new File("src");
System.out.println(file1.isDirectory()); // true

2.3.20 boolean isFile()

判别 path 是否为文件。

// 目录状况跟上面的 2.3.19 相同
// 当是文件的时分
File file1 = new File("test");
System.out.println(file1.isFile()); // true
// 当是文件夹的时分
File file1 = new File("src");
System.out.println(file1.isFile()); // false
// 当途径不存在的时分
File file1 = new File("src1");
System.out.println(file1.isFile()); // false

2.3.21 boolean isHidden()

判别途径是不是处于躲藏的状况。

/*
先看看目录状况
drwxr-xr-x@ 13 wujingyue  staff   416B Jun 19 21:03 .
drwxr-xr-x   4 wujingyue  staff   128B Jun 12 21:19 ..
-rw-r--r--@  1 wujingyue  staff   344B Jun 11 14:50 .gitignore
drwxr-xr-x@  6 wujingyue  staff   192B Jun 11 15:06 .idea
--wx------   1 wujingyue  staff    13K Jun 11 22:20 01.jpg
lrwxr-xr-x@  1 wujingyue  staff    52B Jun 19 21:03 02.jpg -> /Users/wujingyue/Downloads/飞书20230611-215059.jpg
-rw-r--r--@  1 wujingyue  staff   423B Jun 11 14:50 fileLearn.iml
drwxr-xr-x@  2 wujingyue  staff    64B Jun 12 21:15 folder
drwxr-xr-x@  3 wujingyue  staff    96B Jun 11 15:06 out
-rw-r--r--@  2 wujingyue  staff    13K Jun 11 21:50 pp.jpg
drwxr-xr-x@  4 wujingyue  staff   128B Jun 19 21:09 src
-rw-r--r--@  1 root       staff     0B Jun 13 21:36 test
lrwxr-xr-x@  1 wujingyue  staff    41B Jun 18 20:51 testlns -> /Users/wujingyue/Downloads/Auto-GPT-0.3.1
*/
// 处于躲藏的文件
File file1 = new File(".gitignore");
System.out.println(file1.isHidden()); // true
// 不躲藏的文件
File file1 = new File("test");
System.out.println(file1.isHidden()); // false
// 途径不存在
File file1 = new File("test1");
System.out.println(file1.isHidden()); // false

2.3.22 boolean mkdir()

依据 path 创立文件夹,假设存在多级文件夹不存在,那么回来 false ,在有权限的状况下只需最终的文件夹( /a/b/c 中的 c )不存在能成功创立文件夹并回来 true

// 在当时文件夹下创立文件夹,原本文件夹不存在
File file1 = new File("test1");
System.out.println(file1.mkdir()); // true
// 在当时文件夹下,原本文件夹存在
File file1 = new File("test");
System.out.println(file1.mkdir()); // false
// 在当时文件下,原本是文件的
File file1 = new File("01.jpg");
System.out.println(file1.mkdir()); // false
// 在当时文件下,多级文件夹不存在
File file1 = new File("src/test1/test2");
System.out.println(file1.mkdir()); // false
// 在没有权限的文件夹下创立文件夹
// sudo mkdir test2
// drwxr-xr-x@ 2 root       staff    64B Jun 19 21:28 test2
File file1 = new File("test2/test3");
System.out.println(file1.mkdir()); // false

2.3.23 boolean mkdirs()

递归创立文件夹,也便是创立多级文件夹;其他跟上面的 boolean mkdir() 相同。

// 其间 b/c/d 都不存在
File file1 = new File("test1/b/c/d");
System.out.println(file1.mkdirs()); // true

2.3.24 boolean createNewFile()

创立文件。在所属文件夹存在而且有权限的状况下才干成功。

// 在已有途径中创立文件
File file1 = new File("test3");
System.out.println(file1.createNewFile()); // true
// 在途径不存在的文件夹中创立文件
File file1 = new File("test4/test5");
System.out.println(file1.createNewFile()); // false
// 在没有权限的文件夹下创立文件
File file1 = new File("test2/test5");
System.out.println(file1.createNewFile()); // false
// 文件自身现已存在
File file1 = new File("test");
System.out.println(file1.createNewFile()); // false

2.3.25 static File ****createTempFile(String prefix, String suffix)

创立包括指定文件前缀和后缀的临时文件。

File test1 = File.createTempFile("test", ".txt");
System.out.println(test1.getPath()); // /var/folders/qt/_fb3rrpn2vgg3jk637w_v1d80000gn/T/test10152188375744504308.txt

2.3.26 static File ****createTempFile(String prefix, String suffix, File directory)

在给出的文件夹中创立包括指定文件前缀和后缀的文件。在创立文件方面跟 boolean createNewFile() 相同,在创立的文件称号方面跟 static File ****createTempFile(String prefix, String suffix) 相同。

// 在当时文件夹下创立文件
File test1 = File.createTempFile("test", ".txt", new File("."));
System.out.println(test1.getPath()); // ./test2146915152605759112.txt
// 当给定的 File 文件夹不存在的时分会抛出反常
File test1 = File.createTempFile("test", ".txt", new File("./test3"));
System.out.println(test1.getPath());
// Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Not a directory

2.3.27 boolean delete()

删去文件或文件夹。我特意测验了一下,即便这个文件夹或文件并没有权限也是能够删去的,这点我没有想了解,可是运转的成果是这样的。只不过我发现假设删去的文件或文件夹所属的文件夹没有权限,那么删去下面的文件或文件夹就会失利

// 删去存在的文件
File file = new File("test");
System.out.println(file.delete()); // true
// 删去存在的文件夹
File file = new File("test2");
System.out.println(file.delete()); // true
// 删去不存在的文件或文件夹
File file = new File("test5");
System.out.println(file.delete()); // false
// 删去包括文件的文件夹 test2/1.txt
File file = new File("test2");
System.out.println(file.delete()); // false
// 删去包括文件夹的文件夹 test1/b/c/d
File file = new File("test1");
System.out.println(file.delete()); // false
// -rw-r--r--  1 root   staff     0B Jun 20 10:29 test1.txt
File file = new File("test1.txt");
System.out.println(file.delete()); // true
// drwxr-xr-x  4 root   staff   128B Jun 20 11:04 test
// -rw-r--r--  1 root  staff     0B Jun 20 11:01 01.txt
// drwxr-xr-x  2 root  staff    64B Jun 20 11:04 folder
File file = new File("test/folder");
System.out.println(file.delete()); // false
File file = new File("test/01.txt");
System.out.println(file.delete()); // false

2.3.28 boolean exists()

判别文件或文件夹是否存在。

// 文件夹 test1
File file = new File("test1");
System.out.println(file.exists()); // true
// 文件 01.jpg
File file = new File("01.jpg");
System.out.println(file.exists());
// 不存在的文件或文件夹
File file = new File("03.jpg");
System.out.println(file.exists()); // false

2.3.29 void deleteOnExit()

当虚拟机退出的删去,这个跟 boolean delete() 不同的是时刻, delete 是当即删去,deleteOnExit 则是虚拟机退出后再删去。其他跟 delete 坚持相同。

// 删去存在的文件夹
File file = new File("test2");
file.deleteOnExit();
while(true){}
// 只需我不完毕程序,这个文件夹一直存在,当我按下 control + c 就会发现文件夹被删去了
// 删去存在的文件
File file = new File("test.txt");
file.deleteOnExit();
while(true){}
// 删去不存在文件或文件夹,看不出任何作用,原本文件或文件夹就不存在
// 删去没有权限的文件或文件夹也是没啥表明,横竖文件或文件夹还存在

2.3.30 String ****getParent()

得到当时文件或文件夹的父级文件夹。

File file = new File("test1/1");
System.out.println(file.getParent()); // test1
File file = new File("test1");
System.out.println(file.getParent()); // null
File file = new File("test2/1/2/3/4");
System.out.println(file.getParent()); // test2/1/2/3
File file = new File("/test2/1/2/3/4");
System.out.println(file.getParent()); // /test2/1/2/3

2.3.31 long lastModified()

获取上一次修正的时刻,假设文件或文件夹不存在回来 0

// 存在的文件夹
File file = new File("test1");
System.out.println(file.lastModified()); // 1687181825968
// 这个便是我昨日新建的文件夹
// 不存在的文件或文件夹
File file = new File("test2");
System.out.println(file.lastModified()); // 0

能够通过 boolean setLastModified(long time) 来修正这个时刻。参数跟回来值相同是毫秒数:

File file = new File("src");
System.out.println(file.lastModified()); // 1687573295654
System.out.println(file.setLastModified(1687273246041L)); // true
System.out.println(file.lastModified()); // 1687273246041
// 能直接修正到未来或曩昔

2.3.32 long length()

假设是文件,则回来文件的内容的长度(字节);假设是文件夹,空文件 64 ,下面有一级文件夹或文件 96 ,每增加一个文件夹或文件就多 32 ,要是下一级,下一级的下一级不核算在内 (这是在我电脑上的体现,由于官方说了文件夹回来的值是未指定)。

// test.txt 文件内容为:wujingyue
File file = new File("test3/test.txt");
System.out.println(file.length()); // 9
// 空文件夹
File file = new File("test4");
System.out.println(file.length()); // 64
// 直接子级有 5 个
// a         b         c         test.txt  test1.txt
File file = new File("test3");
System.out.println(file.length()); // 224

2.3.33 String [] list()

回来文件夹中的文件和文件夹。

File file = new File("test3");
System.out.println(Arrays.toString(file.list()));
// 回来的数据为: [test1.txt, a, test.txt, c, b]
// 假设传入的是文件
File file = new File("test3/test.txt");
System.out.println(Arrays.toString(file.list())); // null
// 假设传入的是不存在的文件夹或文件
File file = new File("test3/e");
System.out.println(Arrays.toString(file.list())); // null
// 假设传入的是空文件夹
File file = new File("test3/c");
System.out.println(Arrays.toString(file.list())); // []

2.3.34 String [] list(FilenameFilter filter)

回来过滤后的成果,过滤接口为:

public interface FilenameFilter {
    /**
     * Tests if a specified file should be included in a file list.
     *
     * @param   dir    the directory in which the file was found.
     * @param   name   the name of the file.
     * @return  {@code true} if and only if the name should be
     * included in the file list; {@code false} otherwise.
     */
    boolean accept(File dir, String name);
}

accept 回来为 true 的通过过滤,不然会被过滤掉。

File file = new File("test3");
System.out.println(Arrays.toString(file.listFiles((dir, filename) -> true)));
// 得到的成果为:[test3/test1.txt, test3/a, test3/test.txt, test3/c, test3/b]
// 现在就相当于没过滤
// 假设我只想要含有 test 的
File file = new File("test3");
System.out.println(Arrays.toString(file.listFiles((dir, filename) -> filename.contains("test"))));
// 现在的成果就为:[test3/test1.txt, test3/test.txt]

2.3.35 File [] listFiles(FileFilter filter)

回来过滤后的成果,过滤接口为:

public interface FileFilter {
    /**
     * Tests whether or not the specified abstract pathname should be
     * included in a pathname list.
     *
     * @param  pathname  The abstract pathname to be tested
     * @return  {@code true} if and only if {@code pathname}
     *          should be included
     */
    boolean accept(File pathname);
}

这个 accept 的参数跟上面不同,这儿是一个子级的 FIle 目标。

File file = new File("test3");
System.out.println(Arrays.toString(file.listFiles((f) -> true)));
// 成果为:[test3/test1.txt, test3/a, test3/test.txt, test3/c, test3/b]
// 跟上面相同过滤掉 a b 这些,保留包括 test 的
File file = new File("test3");
System.out.println(Arrays.toString(file.listFiles((f) -> f.getName().contains("test"))));
// 成果为:[test3/test1.txt, test3/test.txt]

2.3.36 boolean renameTo(File dest)

对文件或文件夹进行重命名,重命名只能对 path 中的最终一个途径或文件名进行更改,比方 a/b/c 中的 c

// 对文件夹进行重命名
File file = new File("test3");
System.out.println(file.renameTo(new File("test3-new"))); // true
// 对文件进行重命名
File file = new File("testlns");
System.out.println(file.renameTo(new File("test"))); // true
// 对没有权限的文件夹进行重命名
// drwxr-xr-x@ 3 root       staff    96B Jun 20 21:27 test2
File file = new File("test2");
System.out.println(file.renameTo(new File("test2-new"))); // false
// 对没有权限的文件进行重命名
// -rw-r--r--@ 1 root       staff    11B Jun 24 10:07 tianzhidao.txt
File file = new File("tianzhidao.txt");
System.out.println(file.renameTo(new File("tianzhidao1.txt"))); // true
// 在没有权限的文件夹下重命名没有权限的文件夹
File file = new File("test2/tianzhidao.txt");
System.out.println(file.renameTo(new File("test2/123.txt"))); // false
// 重命名的一起修正文件途径
File file = new File("tianzhidao1.txt");
System.out.println(file.renameTo(new File("test/tianzhidao2.txt"))); // false