java之File类【详解】
写在前面
本博客中所有的操作目录,均在D:下载的电影 目录下,结构如下:
概述
java.io.File
是文件和目录路径名的抽象表现形式,其中定义了一些与平台无关的方法来操作文件,主要用于文件和目录的创建、查找和删除等操作。
java.io.File
既可以表示文件,也可以表示文件夹(目录)。
很多应用场景需要使用到java.io.File
类,比如说查看文件的修改日期,文件的类型、目录、大小和读写权限,文件上传与下载,文件的创建、删除、检索以及备份等等。
java.io.File
操作的是文件属性,并非文件内容。
File 类的实例不可变,一旦创建了一个File对象,那么它表示的抽象路径名将永不改变。
静态成员变量
public static final String pathSeparator : 与系统有关的路径分隔符("" + pathSeparatorChar)。
public static final char pathSeparatorChar : 与系统有关的路径分隔符。
public static final String separator : 与系统有关的默认名称分隔符("" + separatorChar)。
public static final char separatorChar :与系统有关的默认名称分隔符。
//与系统有关的文件名称分隔符,windows为反斜杠 \ linux为正斜杠 /
public static final char pathSeparatorChar = fs.getPathSeparator();
public static final String pathSeparator = "" + pathSeparatorChar;
//与系统有关的路径分隔符(windows为冒号 ; linux系统为分号 :
public static final char separatorChar = fs.getSeparator();
public static final String separator = "" + separatorChar;
文件路径
- 绝对路径:完整路径,是指文件在硬盘上真正存在的路径,也就是以盘符(C: or D:)开始的路径,比如 D:\下载的电影\Japanese\学习.avi。
- 相对路径:相对于目标文件的位置,比如以 D:\下载的电影\Japanese\学习.avi 为参考位置,那么 D:\下载的电影\欧美\观摩.rmvb 的相对路径为 …/欧美/观摩.rmvb。
注意:
- 文件路径不区分大小写
- windwos系统的文件名称分隔符使用反斜杠,而反斜杠是转义字符,所以在java语言中,两个反斜杠代表一个普通的反斜杠。
构造方法
public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。
public File(URI uri) : 通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。
注意
- File类对象的构造并不依赖于传入路径是否真实存在。
- File类对象的地址是否合法是通过枚举类 pathStatus 进行判定的。
/**
* Enum type that indicates the status of a file path.
*/
private static enum PathStatus { INVALID, CHECKED };
获取方法
public String getAbsolutePath() :获取File的绝对路径。
public String getPath() :获取File的构造路径。
public String getName() :获取File的名称。
public long length() :获取File的字节大小。
public String getParent():获取File的父目录路径;如果没有,则返回 null。
public long lastModified() : 获取File文件最后一次修改的时间(毫秒)。
代码示例:
import java.io.File;
/**
* @author layman
*/
public class Demo01 {
public static void main(String[] args) {
File file = new File("Japanese\\学习.avi");
// 获取绝对路径
System.out.println("文件绝对路径: " + file.getAbsolutePath()); // D:\下载的电影\Japanese\学习.avi
// 将抽象路径名转换为一个路径名字符串。
System.out.println("文件构造路径: " + file.getPath()); // Japanese\学习.avi
// 获取父目录路径名字符串
System.out.println("父目录路径: " + file.getParent()); // Japanese
// 获取抽象路径名表示的文件或文件夹(末尾部分)
System.out.println("文件名称: " + file.getName()); // 学习.avi
/**
*获取文件大小,以字节为单位。如果路径名不存在,则返回 0
*(注意:文件夹是没有大小的,也返回0)
*/
System.out.println("文件大小:" + file.length() + " 字节"); //1,325,116,788
System.out.println("文件最后的修改时间:" + file.lastModified() + " 毫秒");
}
}
运行结果:
文件绝对路径: D:\下载的电影\Japanese\学习.avi
文件构造路径: Japanese\学习.avi
父目录路径: Japanese
文件名称: 学习.avi
文件大小:1,325,116,788 字节
文件最后的修改时间:1608649905362 毫秒
判断方法
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isFile() :此File表示的是否为文件。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isAbsolute() :此抽象路径名是否为绝对路径名。
public boolean isHidden() : 此File表示的文件或目录是否是一个隐藏文件。
public boolean canExecute() :测试此File表示的文件或目录是否能被执行
public boolean canRead():测试此File表示的文件或目录是否能被读取
public boolean canWrite():测试此File表示的文件或目录是否能被修改
代码示例:
import java.io.File;
/**
* @author layman
*/
public class Demo02 {
public static void main(String[] args) {
File file = new File("D:\\下载的电影\\Japanese\\学习.avi");
File file1 = new File("D:\\下载的电影\\Japanese");
File file2 = new File("津巴布韦\\学习.avi");
// 判断文件或文件夹是否存在
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否存在:" + file.exists());
System.out.println("津巴布韦\\学习.avi 是否存在:" + file2.exists());
System.out.println("--------------------------------------------------");
// 判断是否为文件或者文件夹
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否是文件:"+ file.isFile());
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否是目录:"+ file.isDirectory());
System.out.println("--------------------------------------------------");
System.out.println("D:\\下载的电影\\Japanese\\Japanese 是否是文件:"+ file1.isFile());
System.out.println("D:\\下载的电影\\Japanese\\Japanese 是否是目录:"+ file1.isDirectory());
System.out.println("--------------------------------------------------");
//判断构造路径是否为绝对路径名
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否为绝对路径: " + file.isAbsolute());
System.out.println("津巴布韦\\学习.avi 是否为绝对路径: " + file2.isAbsolute());
System.out.println("--------------------------------------------------");
// 判断文件或文件夹是否隐藏
System.out.println("D:\\下载的电影\\Japanese 是否隐藏: " + file1.isHidden());
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否隐藏: "+file.isHidden());
System.out.println("--------------------------------------------------");
// 判断文件或文件夹是否能被执行
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否能被执行:" + file.canExecute());
System.out.println("--------------------------------------------------");
// 判断文件或文件夹是否能被读取
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否能被读取:" + file.canRead());
System.out.println("--------------------------------------------------");
// 判断文件或文件夹是否能被修改
System.out.println("D:\\下载的电影\\Japanese\\学习.avi 是否能被修改:" + file.canWrite());
}
}
运行结果:
D:\下载的电影\Japanese\学习.avi 是否存在:true
津巴布韦\学习.avi 是否存在:false
--------------------------------------------------
D:\下载的电影\Japanese\学习.avi 是否是文件:true
D:\下载的电影\Japanese\学习.avi 是否是目录:false
--------------------------------------------------
D:\下载的电影\Japanese\Japanese 是否是文件:false
D:\下载的电影\Japanese\Japanese 是否是目录:true
--------------------------------------------------
D:\下载的电影\Japanese\学习.avi 是否为绝对路径: true
津巴布韦\学习.avi 是否为绝对路径: false
--------------------------------------------------
D:\下载的电影\Japanese 是否隐藏: false
D:\下载的电影\Japanese\学习.avi 是否隐藏: true
--------------------------------------------------
D:\下载的电影\Japanese\学习.avi 是否能被执行:true
--------------------------------------------------
D:\下载的电影\Japanese\学习.avi 是否能被读取:true
--------------------------------------------------
D:\下载的电影\Japanese\学习.avi 是否能被修改:false
创建删除方法
public boolean createNewFile() :若当前file表示的路径不存在,则创建该文件(文件夹
public static File createTempFile(String prefix,String suffix) :使用给定前缀和后缀,在与系统有关的默认临时文件目录中创建一个空文件。调用此方法等同于调用 createTempFile(prefix, suffix, null)。
public static File createTempFile(String prefix,String suffix,File directory) :使用给定前缀和后缀,在指定目录中创建一个空文件。
public boolean mkdir() :创建此抽象路径名指定的目录。
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。如果失败,也可能已经成功创建了一部分目录。
public boolean delete() :删除文件或文件夹。如果是文件夹,那么必须是空文件夹才能被删除。
代码演示:
import java.io.File;
import java.io.IOException;
/**
* @author layman
*/
public class Demo03 {
public static void main(String[] args) throws IOException {
// 创建文件
File file = new File("D:\\下载的电影\\Japanese\\激情.avi");
System.out.println("文件是否存在: " + file.exists()); // false
System.out.println("文件是否创建成功: " + file.createNewFile()); // true
System.out.println("文件是否存在: " + file.exists()); // true
System.out.println("----------------------");
// 创建单个目录
File file2= new File("D:\\下载的电影\\欧美");
System.out.println("目录是否存在: " + file2.exists());// false
System.out.println("目录是否创建: " + file2.mkdir()); // true
System.out.println("目录是否存在: " + file2.exists());// true
System.out.println("----------------------");
// 创建多级目录
File file3= new File("D:\\下载的电影\\欧美\\德国\\柏林");
System.out.println("多级目录是否创建成功: " + file3.mkdirs());
System.out.println("----------------------");
// 删除文件
System.out.println("文件是否删除成功:" + file.delete());
System.out.println("----------------------");
// 删除非空目录(欧美 目录),该目录下有德国和柏林目录,所以删除失败
System.out.println("欧美目录是否删除成功:"+ file2.delete());
System.out.println("----------------------");
// 删除空目录 (柏林 目录) ,该目录为空,删除成功
System.out.println("柏林目录是否删除成功:" + file3.delete());
}
}
运行结果:
文件是否存在: false
文件是否创建成功: true
文件是否存在: true
----------------------
目录是否存在: false
目录是否创建: true
目录是否存在: true
----------------------
多级目录是否创建成功: true
----------------------
文件是否删除成功:true
----------------------
欧美目录是否删除成功:false
----------------------
柏林目录是否删除成功:true
遍历方法
public String[] list() :返回一个String数组,表示该File目录中的所有文件和文件夹的名称
public File[] listFiles() :和list()方法类似,区别是它返回一个File数组。
public String[] list(FilenameFilter filter) :根据过滤器,筛选出File目录中符合条件的文件和文件夹的名称
public File[] listFiles(FilenameFilter filter):和list(FilenameFilter filter)方法类似,区别是它返回的是一个file数组。
public File[] listFiles(FileFilter filter):和listFiles(FilenameFilter filter)方法类似,区别是它的参数是一个FileFilter
public static File[] listRoots() : 获取系统盘符名称(windows为C盘,D盘等,linux为 / )
- 遍历的均为对应目录下的 文件 和 文件夹 (不包括子文件夹和子文件夹中的文件)
- 以上方法均可 获取隐藏文件和文件夹
操作目录:
代码演示:
import java.io.File;
import java.util.Arrays;
/**
* @author layman
*/
public class Demo04 {
public static void main(String[] args) {
File file= new File("D:\\下载的电影");
// public String[] list()
System.out.println(Arrays.toString(file.list()));
System.out.println("---------------------------");
// public File[] listFiles()
System.out.println(Arrays.toString(file.listFiles()));
System.out.println("---------------------------");
// public String[] list(FilenameFilter filter)
// 获取所有名称以.3gp结尾的文件和文件夹
String[] list = file.list((File dir, String name) ->
name.endsWith(".3gp")
);
System.out.println(Arrays.toString(list));
System.out.println("---------------------------");
// public File[] listFiles(FilenameFilter filter)
// 获取所有名称以.avi结尾的文件和文件夹
File[] files = file.listFiles((File dir, String name) ->
name.endsWith(".avi")
);
System.out.println(Arrays.toString(files));
System.out.println("---------------------------");
//public File[] listFiles(FileFilter filter)
// 获取文件名包含avi且不是文件夹,且可以修改的文件
File[] files1 = file.listFiles((File pathname) ->{
if(pathname.isDirectory()){
return false;
}
// pathname.length() > 41943040L
return pathname.getName().contains("avi") && pathname.canWrite();
});
System.out.println(Arrays.toString(files1));
System.out.println("---------------------------");
// 获取系统所有盘符
File[] files2 = File.listRoots();
System.out.println(Arrays.toString(files2));
}
}
运行结果:
[Japanese, 愤怒的香蕉.avi, 我有两把枪.3gp, 日出江花红似火.avi, 法外狂徒.3gp]
---------------------------
[D:\下载的电影\Japanese, D:\下载的电影\愤怒的香蕉.avi, D:\下载的电影\我有两把枪.3gp, D:\下载的电影\日出江花红似火.avi, D:\下载的电影\法外狂徒.3gp]
---------------------------
[我有两把枪.3gp, 法外狂徒.3gp]
---------------------------
[D:\下载的电影\愤怒的香蕉.avi, D:\下载的电影\日出江花红似火.avi]
---------------------------
[D:\下载的电影\愤怒的香蕉.avi]
---------------------------
[C:\, D:\, E:\, F:\, G:\]
源码注释:
//返回一个String数组,表示该File目录中的所有文件和文件夹的名称
public String[] list() {
//获取Java安全管理器
SecurityManager security = System.getSecurityManager();
if (security != null) {
// 检测是否有读取权限
security.checkRead(path);
}
//检测文件路径是否有效
if (isInvalid()) {
return null;
}
// 通过fs(平台的本地文件系统对象)遍历传入的文件路径
return fs.list(this);
}
//和list()方法类似,区别是它返回一个File数组。
public File[] listFiles() {
// 获取文件数组
String[] ss = list();
if (ss == null) return null;
int n = ss.length;
// 根据文件名数组长度创建file数组
File[] fs = new File[n];
//创建file对象并存入file数组
for (int i = 0; i < n; i++) {
// private File(String child, File parent)
//this:传入的文件路径
//ss[i]:遍历出的文件或文件夹的名称
fs[i] = new File(ss[i], this);
}
return fs;
}
//根据过滤器,筛选出File目录中符合条件的文件和文件夹的名称
public String[] list(FilenameFilter filter) {
// 获取文件数组
String names[] = list();
// 如果filter == null,该方法等同于 list()
if ((names == null) || (filter == null)) {
return names;
}
List<String> v = new ArrayList<>();
for (int i = 0 ; i < names.length ; i++) {
// this:传入的路径名 name[i] 遍历的文件数组
if (filter.accept(this, names[i])) {
// 过滤成功,把文件数组对应下标的值存入list集合中
v.add(names[i]);
}
}
// 将符合过滤条件的list集合,转为String数组 并返回
return v.toArray(new String[v.size()]);
}
// 和list(FilenameFilter filter)方法类似,区别是它返回的是一个file数组。
public File[] listFiles(FilenameFilter filter) {
// 获取文件数组
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
// 遍历数组,并筛选复合条件的文件和文件夹,存入list集合
for (String s : ss)
if ((filter == null) || filter.accept(this, s))
// private File(String child, File parent)
files.add(new File(s, this));
// 将ArrayList集合转为file数组,并返回
return files.toArray(new File[files.size()]);
}
// 和listFiles(FilenameFilter filter)方法类似,区别是它的参数是一个FileFilter
public File[] listFiles(FileFilter filter) {
// 获取文件数组
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
// 遍历数组,并筛选复合条件的文件和文件夹,存入list集合
for (String s : ss) {
// 根据文件数组创建file对象
File f = new File(s, this);
// 根据FileFilter进行过滤
if ((filter == null) || filter.accept(f))
files.add(f);
}
// 把ArrayList集合转为file数组并返回
return files.toArray(new File[files.size()]);
}
设置方法
public boolean setExecutable(boolean executable): 设置所有者对此file对象的执行权限,等同于file.setExecutable(boolean executable, true)
public boolean setExecutable(boolean executable,boolean ownerOnly) : 设置此file对象的所有者或所有用户的执行权限。
public boolean setLastModified(long time): 设置此file对象最后一次修改时间
public boolean setReadable(boolean readable): 设置所有者对此file对象的读权限,等同于file.setReadable(boolean readable, true)
public boolean setReadable(boolean readable,boolean ownerOnly): 设置此file对象的的所有者或所有用户的读权限。
public boolean setReadOnly() : 设置此file对象为只读
public boolean setWritable(boolean writable): 设置所有者对此file对象的写权限,等同于file.setWritable(boolean writable, true)
public boolean setWritable(boolean writable,boolean ownerOnly): 设置此file对象的的所有者或所有用户的写权限。
重命名方法
public boolean renameTo(File dest) : 重新命名此抽象路径名表示的文件。
- renameTo方法类似于剪切并重命名。
- 如果源文件不存在,则该操作失败。
- 如果源文件和目标文件不在同一目录下,且目标文件不存在,则该操作可能成功,也可能失败。
- 如果源文件和目标文件在同一目录下,且目标文件存在,则该操作成功。
- 文件夹只能重命名为文件夹。
- 文件只能重命名为文件。
- 重命名文件夹,只有当该文件夹为空文件夹时,该操作才会成功。
代码演示:
import java.io.File;
/**
* @author layman
* @date 2021/3/4
*/
public class Demo05 {
public static void main(String[] args) {
// 重命名文件(目标文件不存在)
File oldFile = new File("D:\\下载的电影\\愤怒的香蕉.avi");
File newFile = new File("D:\\下载的电影\\Japanese\\愤怒的大象.avi");
/**
* 1. 如果源文件(oldFile)不存在,则返回失败
* 2. 如果源文件(oldFile)和目标文件(newFile)不在同一目录下,则该操作相当于剪切并重命名
* 3. 如果源文件(oldFile)和目标文件(newFile)一致,则该操作返回成功
* 3. 如果目标文件已存在,则该操作失败
* 4. 文件夹只能重命名为文件夹
* 5. 文件只能重命名为文件
*
*/
System.out.println("重命名操作是否成功: " + oldFile.renameTo(newFile));
System.out.println("-----------------------");
// 重命名文件(目标文件存在)
File oldFile1 = new File("D:\\下载的电影\\法外狂徒.3gp");
File newFile1 = new File("D:\\下载的电影\\Japanese\\法外狂徒.3gp");
System.out.println("重命名操作是否成功: " + oldFile1.renameTo(newFile1));
System.out.println("-----------------------");
// 重命名文件夹(目标文件不存在)
File oldFile2 = new File("D:\\下载的电影\\我有两把枪");
File newFile2= new File("D:\\下载的电影\\Japanese\\一把叫啊");
System.out.println("重命名操作是否成功: " + oldFile2.renameTo(newFile2));
System.out.println("-----------------------");
// 重命名文件夹(目标文件存在)
File oldFile4 = new File("D:\\下载的电影\\日出江花红似火");
File newFile4= new File("D:\\下载的电影\\Japanese\\日出江花红似火");
System.out.println("重命名操作是否成功: " + oldFile4.renameTo(newFile4));
}
}
运行结果:
重命名操作是否成功: true
-----------------------
重命名操作是否成功: false
-----------------------
重命名操作是否成功: true
-----------------------
重命名操作是否成功: false