printwriter 和 filewriter 的正确使用

The proper uses of a print writer and file writer

既然可以直接使用print writer,为什么还要用file writer,然后再用print writer包装呢?我们使用缓冲读取器,这样它们就可以一次读取大量数据,但是为了打印输出,我们必须将它们循环到一个 while 循环中,为什​​么我们没有更简单的方法来打印输出?

让我们先看看主要区别的 javadoc。

FileWriter

Convenience class for writing character files. The constructors of this class assume that the default character encoding ... FileWriter is meant for writing streams of characters.

PrintWriter

Prints formatted representations of objects to a text-output stream.

这意味着FileWriter专注于字符输出,您无法定义字符编码。而 PrintWriter 专注于格式化文本输出,您可以指定字符编码。

找个小例子作为演示

// we need this as there is no convenient method to output a platform
// specific line separator charcater(s)
String newLine = System.getProperty("line.separator");
try (FileWriter fw = new FileWriter("/tmp/fw.txt")) {
    fw.append('\u2126').append(newLine);
    fw.write(65);
    fw.append(newLine);
    fw.append(String.format("%10s: %s%n", "some", "value"));
    fw.append("some line").append(newLine);
} catch (IOException ex) {
    System.err.println("something failed: " + ex.getMessage());
}
// the println() methods will append the right platform specific line separator
// charcater(s)
try (PrintWriter pw = new PrintWriter("/tmp/pw.txt", "UTF8")) {
    pw.append('\u2126');
    pw.println();
    pw.write(65);
    pw.println();
    pw.printf("%10s: %s%n", "some", "value");
    pw.println("some line");
} catch (FileNotFoundException | UnsupportedEncodingException ex) {
    System.err.println(ex.getMessage());
}

如果您 运行 识别 unicode 的机器上的片段(或 运行 代码为 java -Dfile.encoding=UTF-8 ...),输出将是

fw.txt

Ω
A
      some: value
some line

pw.txt

Ω
A
      some: value
some line

对于上述示例,代码和结果看起来大致相同。 PrintWriter提供格式化输出的方法,而FileWriter你必须在输出前进行格式化。

但是当您的环境不识别 unicode(或 运行 代码为 java -Dfile.encoding=ISO-8859-1 ...)时,就会出现很大的不同

fw.txt

?
A
      some: value
some line

Unicode omega 字符无法使用 ISO8859-1 编码打印。

使用 PrintWriter 我们定义了输出的字符编码。这与环境的默认编码无关。

pw.txt

Ω
A
      some: value
some line

回到你的问题。将 FileWriter 包装成 PrintWriter。有可能的。但是你失去了主要的好处,选择字符编码的能力。

try (PrintWriter pw = new PrintWriter(new FileWriter("/tmp/pwfw.txt"))) {
    pw.append('\u2126');
    pw.println();
} catch (IOException ex) {
    System.err.println("something failed: " + ex.getMessage());
}

文件 pwfw.txt 仅当环境的默认编码为 un​​icode 时才会包含 unicode 字符 omega。所以你会有与 FileWriter.

相同的限制(对于编码)

如果你必须使用FileWriterPrintWriter取决于你的需要。我相信 PrintWriter 大多数时候应该这样做。