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

注意:

  1. 文件路径不区分大小写
  2. 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
posted @ 2021-03-05 20:31  layman~  阅读(107)  评论(0编辑  收藏  举报