Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

  • Java核心基础

    • 多线程

    • Java常用类

    • 枚举类与注解

    • Java集合

    • 数据结构与算法

    • 泛型

    • IO流

      • IO流概述
      • File对象
        • File
          • 实例化
          • 路径方法
          • 分隔符
          • 文件和目录
          • 创建和删除文件
          • 遍历文件和目录
          • 创建目录和删除目录
          • 重命名
        • Path
        • 小结
      • InputStream
      • OutputStream
      • Filter模式
      • 操作Zip
      • 读取classpath资源
      • 序列化
      • Reader
      • Writer
      • 转换流
      • PrintStream和PrintWriter
      • RandomAccessFile
      • Files工具类
    • 网络编程

    • 反射

    • 函数式编程

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java核心基础
  • IO流
SaulJWu
2021-01-07

File对象

# File

在计算机系统中,文件是非常重要的存储方式。Java的标准库java.io提供了File对象来操作文件和目录。

# 实例化

要构造一个File对象,需要传入文件路径:

public class Main {
    public static void main(String[] args) {
        File f = new File("C:\\Windows\\notepad.exe");
        System.out.println(f);
    }
}
1
2
3
4
5
6

运行结果:

C:\Windows\notepad.exe
1

构造File对象时,既可以传入绝对路径,也可以传入相对路径。

  • 绝对路径是以根目录开头的完整路径,例如:
File f = new File("C:\\Windows\\notepad.exe");
1

注意Windows平台使用\作为路径分隔符,在Java字符串中需要用\\表示一个\。

Linux平台使用/作为路径分隔符:

File f = new File("/usr/bin/javac");
1
  • 传入相对路径时,相对路径前面加上当前目录就是绝对路径:
// 假设当前目录是C:\Docs
File f1 = new File("sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File(".\\sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File("..\\sub\\javac"); // 绝对路径是C:\sub\javac
1
2
3
4

可以用.表示当前目录,..表示上级目录。

# 路径方法

File对象有3种形式表示的路径,

  • 一种是getPath(),返回构造方法传入的路径,
  • 一种是getAbsolutePath(),返回绝对路径,
  • String getParent():获取上层文件目录路径。若无,返回null
  • 一种是getCanonicalPath,它和绝对路径类似,但是返回的是规范路径。
public class Main {
    public static void main(String[] args) throws IOException {
        File f = new File("..");
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getCanonicalPath());
    }
}
1
2
3
4
5
6
7
8

运行结果:

..
/app/..
/
1
2
3

绝对路径可以表示成C:\Windows\System32\..\notepad.exe,而规范路径就是把.和..转换成标准的绝对路径后的路径:C:\Windows\notepad.exe。

# 分隔符

因为Windows和Linux的路径分隔符不同,File对象有一个静态变量用于表示当前平台的系统分隔符:

System.out.println(File.separator); // 根据当前平台打印"\"或"/"
1
  • 举例:使用静态变量可以保证路径在Windows和Linux上都能正常访问了。

image-20210107175905810

# 文件和目录

File对象既可以表示文件,也可以表示目录。特别要注意的是,构造一个File对象,即使传入的文件或目录不存在,代码也不会出错,因为构造一个File对象,并不会导致任何磁盘操作。只有当我们调用File对象的某些方法的时候,才真正进行磁盘操作。

例如,调用isFile(),判断该File对象是否是一个已存在的文件,调用isDirectory(),判断该File对象是否是一个已存在的目录:

public class Main {
    public static void main(String[] args) throws IOException {
        File f1 = new File("C:\\Windows");
        File f2 = new File("C:\\Windows\\notepad.exe");
        File f3 = new File("C:\\Windows\\nothing");
        System.out.println(f1.isFile());
        System.out.println(f1.isDirectory());
        System.out.println(f2.isFile());
        System.out.println(f2.isDirectory());
        System.out.println(f3.isFile());
        System.out.println(f3.isDirectory());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

运行结果:

false
false
false
false
false
false
1
2
3
4
5
6

看来上面的代码都没能获取到文件和目录。

用File对象获取到一个文件时,还可以进一步判断文件的权限和大小:

  • boolean exists():是否存在。
  • boolean canRead():是否可读;
  • boolean canWrite():是否可写;
  • boolean canExecute():是否可执行;
  • boolean isHidden:是否隐藏。
  • long length():文件字节大小。
  • long lastModified():获取最后一次的修改时间,毫秒值

对目录而言,是否可执行表示能否列出它包含的文件和子目录。

# 创建和删除文件

当File对象表示一个文件时,可以通过createNewFile()创建一个新文件,用delete()删除该文件:

File file = new File("/path/to/file");
if (file.createNewFile()) {
    // 文件创建成功:
    // TODO:
    if (file.delete()) {
        // 删除文件成功:
    }
}
1
2
3
4
5
6
7
8

有些时候,程序需要读写一些临时文件,File对象提供了createTempFile()来创建一个临时文件,以及deleteOnExit()在JVM退出时自动删除该文件。

public class Main {
    public static void main(String[] args) throws IOException {
        File f = File.createTempFile("tmp-", ".txt"); // 提供临时文件的前缀和后缀
        f.deleteOnExit(); // JVM退出时自动删除
        System.out.println(f.isFile());
        System.out.println(f.getAbsolutePath());
    }
}
1
2
3
4
5
6
7
8

# 遍历文件和目录

当File对象表示一个目录时,可以使用list()和listFiles()列出目录下的文件和子目录名。

  • public String[] list():获取指定目录下的所有文件或者文件目录的名称数组
  • public File[] listFiles():获取指定目录下的所有文件或者文件目录的File数组

listFiles()提供了一系列重载方法,可以过滤不想要的文件和目录:

public class Main {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Windows");
        File[] fs1 = f.listFiles(); // 列出所有文件和子目录
        printFiles(fs1);
        File[] fs2 = f.listFiles(new FilenameFilter() { // 仅列出.exe文件
            public boolean accept(File dir, String name) {
                return name.endsWith(".exe"); // 返回true表示接受该文件
            }
        });
        printFiles(fs2);
    }

    static void printFiles(File[] files) {
        System.out.println("==========");
        if (files != null) {
            for (File f : files) {
                System.out.println(f);
            }
        }
        System.out.println("==========");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

运行结果

==========
==========
==========
==========
1
2
3
4

# 创建目录和删除目录

和文件操作类似,File对象如果表示一个目录,可以通过以下方法创建和删除目录:

  • boolean mkdir():创建当前File对象表示的目录;
  • boolean mkdirs():创建当前File对象表示的目录,并在必要时将不存在的父目录也创建出来;
  • boolean delete():删除当前File对象表示的目录,当前目录必须为空才能删除成功。

# 重命名

boolean renameTo(File dest):把文件重命名为指定的文件路径。

看来Java让我们不仅能重命名并且也移动到指定的路径,但是如果指定的路径存在同名的文件,肯定是失败的。

# Path

Java标准库还提供了一个Path对象,它位于java.nio.file包。Path对象和File对象类似,但操作更加简单:

public class Main {
    public static void main(String[] args) throws IOException {
        Path p1 = Paths.get(".", "project", "study"); // 构造一个Path对象
        System.out.println(p1);
        Path p2 = p1.toAbsolutePath(); // 转换为绝对路径
        System.out.println(p2);
        Path p3 = p2.normalize(); // 转换为规范路径
        System.out.println(p3);
        File f = p3.toFile(); // 转换为File对象
        System.out.println(f);
        for (Path p : Paths.get("..").toAbsolutePath()) { // 可以直接遍历Path
            System.out.println("  " + p);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

运行结果:

./project/study
/app/./project/study
/app/project/study
/app/project/study
  app
  ..
1
2
3
4
5
6

如果需要对目录进行复杂的拼接、遍历等操作,使用Path对象更方便。

# 小结

File类中涉及到关于文件或目录的创建、删除、重命名、修改时间、文件大小等方法,并未设计到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流。

后续File类的对象常会作为参数传递到流的构造中,指明读取或写入的“终点”。

帮我改善此页面 (opens new window)
#File#文件#目录
上次更新: 2021/01/08, 01:19:19
IO流概述
InputStream

← IO流概述 InputStream→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式