1. 引言
在编程中几乎总要与文件打交道。大家都熟悉的例子有:保存便笺文本、游戏进度、复制图片或从配置文件中读取设置。
在 Java 中,我们有现代且好用的工具:来自 java.nio.file 包的 Path 和 Files。它们让你用几行代码就能打开文件、读取其内容、写入文本,甚至复制图片。
文件路径(Path)
文件总是位于磁盘上的某个位置,要访问它就需要指定路径。为此,Java 提供了 Path 类,可以通过 Path.of() 方法创建新对象。
Path path = Path.of("hello.txt"); // 相对路径
Path absPath = Path.of("C:/Users/Me/image.png"); // 绝对路径(Windows)
说明:
- 相对路径会在当前项目文件夹中查找文件(例如 "hello.txt")。
- 绝对路径给出完整地址:磁盘、文件夹以及文件名。
2. 处理文本文件
从 Java 的角度看,文件大致分为两类:文本文件和二进制文件。若其内容可以表示为人类可读的文本——那就是文本文件。其他情况则是字节的集合(即二进制文件)。
将文本写入文件 — writeString
要把字符串写入文件,使用 writeString 方法。
Path p = Path.of("hello.txt");
Files.writeString(p, "你好,文件!");
这里发生了什么:
- 创建一个指向 "hello.txt" 的 Path 对象;
- 通过 writeString 方法把字符串写进去;
- 如果文件不存在,将会自动创建。
这样就可以轻松地把便笺或消息保存到文本文件中。
从文件读取文本 — readString
readString 方法可以一次性把整个文件加载为一个字符串。
Path p = Path.of("hello.txt");
String content = Files.readString(p);
System.out.println(content);
现在变量 content 中保存着文件内容。这对于体积较小的文件很方便:配置、文本、JSON 文档等。
3. 处理二进制文件
并非所有文件都是文本。图片、音乐、压缩包——本质上都是字节序列。处理它们可以使用 write 和 readAllBytes 方法。
将字节写入文件 — write
write() 方法可以把字节数组写入文件,也称之为缓冲区(byte buffer)。
byte[] data = {65, 66, 67, 68}; // 字符 A B C D
Files.write(Path.of("letters.bin"), data);
这里我们把一个字节数组写入了文件。如果把该文件按文本方式打开,里面会是 "ABCD" 这几个字母。
读取字节 — readAllBytes
要把文件内容重新读回为字节数组,可以使用 readAllBytes 方法。
byte[] buffer = Files.readAllBytes(Path.of("letters.bin"));
// 将读取的字节数组打印到屏幕
for (byte b : buffer)
{
System.out.print((char)b + " ");
}
屏幕输出:
A B C D
这种方式可用于处理任何二进制文件——图片、文档、音乐。
4. 常见文件操作场景
最常见的文件操作,大概就是复制文件了。
复制文件
要复制一个文件,可以先把它读入字节数组,再写入到另一个文件。
Path in = Path.of("logo.png");
Path out = Path.of("logo_copy.png");
byte[] bytes = Files.readAllBytes(in);
Files.write(out, bytes);
通过这种方式可以复制图片、文档以及任何其他文件,而无需关心其格式。
检查存在与大小
有时需要确认文件是否存在,并获取其大小。可使用 exists 和 size 方法。
Path p = Path.of("hello.txt");
if (Files.exists(p))
{
long size = Files.size(p);
System.out.println("找到文件,大小: " + size + " 字节");
}
else
{
System.out.println("未找到文件!");
}
这有助于诊断:你将明确知道自己是否在处理正确的文件。
5. 异常
文件操作可能会失败:文件不存在、没有访问权限、磁盘已满或者文件被其他程序占用。因此应当把与磁盘交互的代码放在 try-catch 中,或通过 throws 将异常抛到外层。
try
{
String content = Files.readString(Path.of("hello.txt"));
System.out.println(content);
}
catch (IOException e)
{
System.out.println("读取时出错: " + e.getMessage());
}
这样程序不会“崩溃”,而是会友好地告知用户发生了什么。必要时,可以通过带有关键字 throws 的方法将 IOException 继续向调用栈上传递。
GO TO FULL VERSION