CodeGym /课程 /JAVA 25 SELF /File、Path、Files 类:概览与对象创建

File、Path、Files 类:概览与对象创建

JAVA 25 SELF
第 35 级 , 课程 1
可用

1. 类 File:一切是如何开始的

尽管我们已经得出结论:在新项目中最好不要使用 File 类,但仍有大量遗留系统在使用它。因此理解它并能熟练使用仍然很重要。File 是一种在磁盘上表示文件或目录的老方式。但不要混淆:File 对象并不是文件本身,而是路径的“指针”/“标识”。例如,表达式 File f = new File("hello.txt"); 并不会在磁盘上创建文件——你只是描述了一个路径。

如何创建 File 对象?

import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File file = new File("example.txt"); // 相对路径
        File folder = new File("mydir");     // 目录

        System.out.println("绝对路径: " + file.getAbsolutePath());
        System.out.println("文件是否存在? " + file.exists());
        System.out.println("是文件吗? " + file.isFile());
        System.out.println("是目录吗? " + folder.isDirectory());
    }
}

需要记住的要点:
创建 File 对象不会在磁盘上创建文件。这只是一个“快捷方式”。要让文件真正出现,需要显式创建(例如写入数据,或调用 file.createNewFile())。

File 类的常用方法

  • exists() — 检查文件/目录是否存在。
  • isFile() — 是否为文件(而非文件夹)。
  • isDirectory() — 是否为目录。
  • getAbsolutePath() — 获取绝对路径。
  • length() — 文件大小(字节)。
  • getName() — 文件或文件夹名称。
  • delete() — 删除文件/目录(如果目录为空)。

示例:输出文件信息

File file = new File("example.txt");
System.out.println("名称: " + file.getName());
System.out.println("路径: " + file.getAbsolutePath());
System.out.println("大小: " + file.length() + " 字节");
System.out.println("存在吗? " + file.exists());

2. 类 Path:对文件的现代视角

Path 是新的文件 API(NIO.2,自 Java 7 起)的一部分。它是文件/目录路径的抽象,而且路径不仅可以位于本地磁盘,还可位于 ZIP 压缩包内,或远程资源上(只要有相应的提供者)。

如果说 File 是一张老式纸质地图,那么 Path 就是 GPS 导航。

如何创建 Path 对象?

import java.nio.file.Path;
import java.nio.file.Paths;

public class PathDemo {
    public static void main(String[] args) {
        Path path1 = Paths.get("example.txt"); // 相对路径
        Path path2 = Paths.get("folder", "file.txt"); // 组合路径片段

        System.out.println("路径 1: " + path1.toAbsolutePath());
        System.out.println("路径 2: " + path2.toAbsolutePath());
    }
}

优点:无需考虑路径分隔符。Paths.get 会根据你的操作系统选择正确的格式。

FilePath 之间的转换

  • FilePath: file.toPath()
  • PathFile: path.toFile()
File file = new File("test.txt");
Path path = file.toPath();

Path anotherPath = Paths.get("data.txt");
File anotherFile = anotherPath.toFile();

路径操作:resolverelativizenormalize

路径拼接(resolve

Path dir = Paths.get("myfolder");
Path file = dir.resolve("notes.txt"); // myfolder/notes.txt
System.out.println(file); // myfolder/notes.txt

相对路径(relativize

Path pathA = Paths.get("folderA/file1.txt");
Path pathB = Paths.get("folderA/subfolder/file2.txt");
Path relative = pathA.relativize(pathB);
System.out.println(relative); // ../subfolder/file2.txt

路径规范化(normalize

Path messy = Paths.get("folder/../folder/file.txt");
Path clean = messy.normalize();
System.out.println(clean); // folder/file.txt

示例:构建文件路径

Path home = Paths.get(System.getProperty("user.home"));
Path docs = home.resolve("Documents");
Path myFile = docs.resolve("myfile.txt");
System.out.println("文件路径: " + myFile.toAbsolutePath());

3. 类 Files:你的瑞士军刀

Files 类位于 java.nio.file 包中,是基于 Path 的文件与目录操作静态工具方法集合。它几乎无所不能:检查存在性、创建/删除、读/写、复制/移动、获取属性以及遍历目录树。

Files 类的常用方法

  • Files.exists(path) — 检查文件/目录是否存在。
  • Files.isDirectory(path) — 是否为目录。
  • Files.size(path) — 文件大小。
  • Files.createFile(path) — 创建文件。
  • Files.createDirectory(path) — 创建目录。
  • Files.delete(path) — 删除文件/目录。
  • Files.copy(src, dest) — 复制文件。
  • Files.move(src, dest) — 移动/重命名。
  • Files.getLastModifiedTime(path) — 最后修改时间。
  • Files.readAllBytes(path) — 将整个文件读入字节数组。
  • Files.readAllLines(path) — 读取文本文件的所有行。
  • Files.write(path, bytes) — 将字节写入文件。

示例:检查文件

import java.nio.file.*;

public class FilesDemo {
    public static void main(String[] args) {
        Path path = Paths.get("example.txt");

        System.out.println("文件是否存在? " + Files.exists(path));
        System.out.println("是目录吗? " + Files.isDirectory(path));

        if (Files.exists(path)) {
            try {
                System.out.println("文件大小: " + Files.size(path) + " 字节");
            } catch (Exception e) {
                System.out.println("获取大小时出错: " + e.getMessage());
            }
        }
    }
}

4. 实践:创建对象并输出属性

为文件和目录创建对象

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class CompareDemo {
    public static void main(String[] args) {
        // 旧方式
        File oldFile = new File("test.txt");
        File oldDir = new File("mydir");

        // 新方式
        Path newFile = Paths.get("test.txt");
        Path newDir = Paths.get("mydir");

        System.out.println("=== File API ===");
        System.out.println("文件: " + oldFile.getAbsolutePath());
        System.out.println("存在吗? " + oldFile.exists());
        System.out.println("是文件吗? " + oldFile.isFile());
        System.out.println("是目录吗? " + oldDir.isDirectory());

        System.out.println("\n=== Path API ===");
        System.out.println("文件: " + newFile.toAbsolutePath());
        System.out.println("存在吗? " + java.nio.file.Files.exists(newFile));
        System.out.println("是文件吗? " + java.nio.file.Files.isRegularFile(newFile));
        System.out.println("是目录吗? " + java.nio.file.Files.isDirectory(newDir));
    }
}

输出文件属性

import java.nio.file.*;

public class FileProperties {
    public static void main(String[] args) {
        Path path = Paths.get("test.txt");

        System.out.println("绝对路径: " + path.toAbsolutePath());
        System.out.println("文件名: " + path.getFileName());
        System.out.println("父目录: " + path.getParent());

        if (Files.exists(path)) {
            try {
                System.out.println("大小: " + Files.size(path) + " 字节");
                System.out.println("最后修改时间: " + Files.getLastModifiedTime(path));
            } catch (Exception e) {
                System.out.println("获取信息时出错: " + e.getMessage());
            }
        } else {
            System.out.println("未找到文件。");
        }
    }
}

5. 对比:File vs Path/Files

功能 File (java.io) Path + Files (java.nio.file)
路径表示 仅本地磁盘 本地磁盘、ZIP、网络资源
路径拼接 通过斜杠手动拼接 通过 resolve 方便拼接
存在性检查 exists() Files.exists(path)
读/写内容 是(Files.readAll...Files.write
获取属性 基础(length()lastModified() 扩展属性与视图
兼容性 适用于所有 Java 版本 Java 7 及更高版本
符号链接支持 有限 完整支持

简述:什么时候用哪一个?

  • 新项目——使用 PathFiles
  • 维护旧代码——有时不得不使用 File

6. 一些有用的细节

相对路径与绝对路径

相对路径是相对于当前工作目录的路径;绝对路径是从文件系统根开始的完整路径。

Path relative = Paths.get("data", "file.txt");
Path absolute = relative.toAbsolutePath();
System.out.println("绝对路径: " + absolute);

跨平台性

PathFiles 会考虑操作系统特性(分隔符、编码等)。不要手写类似 "C:\\folder\\file.txt" 的路径——请使用 Paths.getresolve

FilePath 的转换

如果你有基于 File 的旧代码,可以很容易地迁移到新 API:

File legacy = new File("legacy.txt");
Path modern = legacy.toPath();
if (Files.exists(modern)) {
    // 现在可以使用 NIO.2 的全部能力
}

检查文件是否存在

Path path = Paths.get("notes.txt");
if (Files.exists(path)) {
    System.out.println("找到文件!");
} else {
    System.out.println("文件不存在。");
}

7. 迷你实践:创建并检查文件和目录

import java.nio.file.*;

public class MiniPractice {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("demo_dir");
        Path file = dir.resolve("hello.txt");

        // 如果目录不存在则创建
        if (!Files.exists(dir)) {
            Files.createDirectory(dir);
            System.out.println("目录已创建: " + dir.toAbsolutePath());
        }

        // 如果文件不存在则创建
        if (!Files.exists(file)) {
            Files.createFile(file);
            System.out.println("文件已创建: " + file.toAbsolutePath());
        }

        // 输出属性
        System.out.println("文件是否存在? " + Files.exists(file));
        System.out.println("是文件吗? " + Files.isRegularFile(file));
        System.out.println("大小: " + Files.size(file) + " 字节");

        // 删除文件和目录(可选)
        Files.delete(file);
        Files.delete(dir);
        System.out.println("文件和目录已删除。");
    }
}

8. 使用 File/Path/Files 时的常见错误

错误 1:混淆 File 与 Path。 许多初学者尝试把 Files 的方法用于 File 对象。请记住:Files.* 只接受 Path。如果你有 File,先调用 file.toPath()。

错误 2:以为创建 File 或 Path 对象会创建文件。 路径对象只是“快捷方式”,不是实际文件。要创建文件请使用 Files.createFile(path) 或写入数据。

错误 3:用字符串手动拼装路径。 不要写 "folder/file.txt""folder\\file.txt"。请使用 Paths.get(...) 和 resolve(...)。这样更安全且跨平台。

错误 4:忽略异常。 文件操作会抛出 IOException 等异常。请通过 try-catch 处理,或向上抛出(throws)。

错误 5:先用 File.exists() 检查,再用 Path 操作。 尽量保持风格一致:既然开始使用 Path,就用 Files.exists(path) 及其他 Files 方法。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION