创建 Scanner 对象
Scanner in = new Scanner(Path.of("file.txt"), StandardCharsets.UTF_8.name());
- 创建路径对象: Paths.of(“file.txt”) 创建了一个指向名为"file.txt" 的文件的路径对象。
- 创建 Scanner 对象: new Scanner(Path.of(“file.txt”), StandardCharsets.UTF_8.name()) 创建了一个新的 Scanner 对象,用于以 UTF-8 编码读取 “file.txt” 文件的内容。UTF-8 编码对于正确解析文件内容非常重要。
创建 PrintWriter 对象
PrintWriter out = new PrintWriter("file_copy.txt", StandardCharsets.UTF_8.name());
- 创建 PrintWriter 对象: new PrintWriter(“file_copy.txt”, StandardCharsets.UTF_8.name()) 创建了一个新的 PrintWriter对象,用于写入 “file_copy.txt” 文件。StandardCharsets.UTF_8.name() 指定了写入文件时使用的字符编码(UTF-8)。
注意
-
文件覆盖: 如果使用 PrintWriter 写入文件时文件已存在,那么文件的内容将被覆盖。如果需要追加内容而不是覆盖,请考虑使用 FileWriter 构造函数的第二个参数设置为 true (可自行动手实验)。
-
资源管理: 由于 Scanner 和 PrintWriter 都涉及文件操作,确保在不再需要它们时关闭这些资源。推荐的做法是使用 try-with-resources 语句或在 finally 块中关闭它们,以避免资源泄露。
-
Path.of和Paths.get在效果上确实非常相似,但它们的使用方式和引入的时间有所不同。
-
Path.of
- 引入时间:Path.of是在Java 11中引入的,作为对Path接口的一个静态方法补充,主要是为了与Java中其他API的命名风格(如Xxx.of)保持一致。
- 使用方法:Path.of(String first, String… more) 是一个静态方法,可以直接通过Path接口调用,用于将一个或多个字符串参数组合成一个Path对象。
-
Paths.get
- 引入时间:Paths.get方法更早地在Java 7(JDK 1.7)中作为java.nio.file.Paths工具类的一部分被引入。
- 使用方法:Paths.get(String first, String… more) 是一个静态方法,通过Paths工具类调用,同样用于将一个或多个字符串参数组合成一个Path对象。
-
-
效果相似性
从功能上讲,Path.of和Paths.get都执行相同的任务:将一个或多个字符串参数连接成一个表示文件系统中路径的Path对象。因此,在大多数情况下,你可以互换使用这两个方法而不会改变程序的行为。 -
使用建议
- 如果你正在使用Java 11或更高版本,并且想要保持代码风格的一致性(即使用Xxx.of的命名模式),那么推荐使用Path.of。
- 如果你正在使用Java 7到Java 10之间的版本,那么你将只能使用Paths.get,因为Path.of在这些版本中还不存在。
- 在编写跨版本兼容的代码时,考虑到Paths.get在更早的版本中就已经存在,因此使用它可能是一个更稳妥的选择,特别是当你的代码需要同时支持多个Java版本时。然而,如果你确定你的代码只会在Java 11或更高版本上运行,那么使用Path.of也是可以的。
示例
下面是优化后的一个完整的示例,展示了如何使用Files.createFile方法创建一个空文件,使用 Scanner 读取文件内容,并使用 PrintWriter 将内容写入另一个文件:
// 导入必要的Java类和接口
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class FileReadWriteExample {
public static void main(String[] args) {
List<String> lines = new ArrayList<>();
Path filePath = Path.of("file.txt");
Path copyFilePath = Paths.get("file_copy.txt");
// 检查file.txt是否存在,如果不存在则创建空文件
try {
if (!Files.exists(filePath)) {
Files.createFile(filePath);
System.out.println("File 'file.txt' was created because it did not exist.");
}
// 使用try-with-resources来读取文件
try (Scanner in = new Scanner(filePath, StandardCharsets.UTF_8.name())) {
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println(line);
lines.add(line);
}
}
// 无需检查file_copy.txt是否存在,因为PrintWriter会自动创建或覆盖文件
try (PrintWriter out = new PrintWriter(copyFilePath.toFile(), StandardCharsets.UTF_8.name())) {
for (String line : lines) {
out.println(line);
}
}
System.out.println("File 'file_copy.txt' has been written successfully.");
} catch (IOException e) {
System.err.println("An I/O error occurred: " + e.getMessage());
}
}
}
上面的代码首先检查file.txt是否存在,如果不存在,则使用Files.createFile方法创建一个空文件。接着,它使用try-with-resources语句来确保Scanner和PrintWriter对象在使用后能够被正确关闭。注意,PrintWriter在打开文件时会自动创建或覆盖现有文件,所以我们不需要提前检查file_copy.txt是否存在。
这样,无论file.txt是否存在,程序都能够顺利进行,并将读取到的内容写入到file_copy.txt中。如果在处理文件时发生任何IOException,程序会捕获异常并输出错误信息。
这个程序是一个基本的文件读写示例,展示了如何使用Java的 Scanner 和 PrintWriter 类来读取和写入文本文件。注意,为了避免读写冲突,程序将读取的内容写入到了一个新的文件 file_copy.txt 中,而不是覆盖原始文件。