1. 概述

Java标准库提供了文件操作的API。PrintWriterFileWriter类有助于将字符写入文件。然而,这两个类设计用于不同的使用场景。

在这个教程中,我们将详细探讨PrintWriterFileWriter在它们的应用场景下的细节,并比较两者之间的异同。

2. PrintWriter

PrintWriter类帮助我们将格式化的文本写入输出流,如文件和控制台。

此外,PrintWriter类的方法不会抛出IOException(可检查异常)。相反,它提供了checkError()方法来了解写入操作的状态。如果写入操作成功,checkError()方法返回false,如果因错误导致失败,则返回true

另外,checkError()方法会在检查错误状态之前刷新流,如果流未关闭的话。

此外,PrintWriter还提供了一个名为flush()的方法,用于在写入操作后显式刷新流。但在使用try-with-resources块时,无需显式刷新流。

2.1. PrintWriter.println()

println()方法将字符串写入输出流并以新行结束。它不能将格式化的文本写入输出流。

此外,如果我们决定不以新行结束字符串,PrintWriter还提供了print()方法。

以下是一个使用println()方法将字符串写入文件的示例:

@Test
void whenWritingToTextFileUsingPrintWriterPrintln_thenTextMatches() throws IOException {
    String result = "I'm going to Alabama\nAlabama is a state in the US\n";
    try (PrintWriter pw = new PrintWriter("alabama.txt");) {
        pw.println("I'm going to Alabama");
        pw.println("Alabama is a state in the US");
    }
    Path path = Paths.get("alabama.txt");
    String actualData = new String(Files.readAllBytes(path));
    assertEquals(result, actualData);
}

这里,我们创建一个PrintWriter对象,参数是文件路径。然后,我们在PrintWriter对象上调用println()方法将字符写入文件。

最后,我们断言预期结果与文件内容相等。

值得注意的是,PrintWriter还提供了write()方法将文本写入文件,我们可以用它替换print()方法。

2.2. PrintWriter.printf()

printf()方法有助于将格式化的文本写入输出流。我们可以使用格式化标识符,如%s%d.2f等,将不同数据类型写入输出流。

让我们看一个使用printf()方法向文件写入格式化数据的示例:

@Test
void whenWritingToTextFileUsingPrintWriterPrintf_thenTextMatches() throws IOException {
    String result = "Dreams from My Father by Barack Obama";
    File file = new File("dream.txt");
    try (PrintWriter pw = new PrintWriter(file);) {
        String author = "Barack Obama";
        pw.printf("Dreams from My Father by %s", author);
        assertTrue(!pw.checkError());
    }
    try (BufferedReader reader = new BufferedReader(new FileReader(file));) {
        String actualData = reader.readLine();
        assertEquals(result, actualData);
    }
}

在上面的代码中,我们向文件写入格式化文本。我们使用%s标识符直接将String类型的数据添加到文本中。

同时,我们创建一个BufferedReader实例,参数是FileReader对象,以便读取文件的内容。

由于方法不会抛出IOException,我们调用checkError()方法了解写入操作的状态。在这种情况下,checkError()返回false,表示没有错误。

3. FileWriter

FileWriter类继承自Writer类。它提供了一个方便的方法,使用预设的缓冲区大小将字符写入文件。

FileWriter不会自动刷新缓冲区,我们需要调用flush()方法。但在使用try-with-resources块时,它会自动在退出块时刷新并关闭流。

此外,如果文件缺失、无法打开等情况,它会抛出IOException

PrintWriter不同,它不能将格式化的文本写入文件。

让我们看一个使用FileWriter类中的write()方法将字符写入File的示例:

@Test
void whenWritingToTextFileUsingFileWriter_thenTextMatches() throws IOException {
    String result = "Harry Potter and the Chamber of Secrets";
    File file = new File("potter.txt");
    try (FileWriter fw = new FileWriter(file);) {
        fw.write("Harry Potter and the Chamber of Secrets");
    }
    try (BufferedReader reader = new BufferedReader(new FileReader(file));) {
        String actualData = reader.readLine();
        assertEquals(result, actualData);
    }
}

在这段代码中,我们创建一个File实例,并将其传递给FileWriter对象。然后,我们在FileWriter对象上调用write()方法将一串字符写入文件。

最后,我们断言预期结果等于文件的内容。

4. 总结

在这篇文章中,我们学习了FileWriterPrintWriter的基本用法及其示例代码。

FileWriter的主要目的是将字符写入文件。然而,PrintWriter功能更强大。它可以将内容写入除了文件之外的其他输出流,并且提供了将格式化文本写入文件或控制台的方法。

如往常一样,示例代码的源代码可以在GitHub上找到:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-io-apis-2