1. 概述

本文将讨论Java I/O包中的PrintWriter类,重点关注其write()print()两个方法的差异。PrintWriter类用于将对象的格式化表示输出到文本输出流,方法不会抛出I/O异常,但构造函数可能抛出异常。使用这些方法前,我们需要通过构造函数提供文件、文件名或输出流作为参数。

2. PrintWriter.write()方法

write()方法有五个重载版本,分别针对charStringint类型。这个方法是向控制台或文件写入数据的一种方式。

  • write(char)write(String)版本可以写入整个数组或字符串,也可以写入部分数组或字符串。
  • write(int)版本则写入一个字符,对应于给定十进制输入的ASCII符号。

首先,看下write(int c)版本:

@Test
void whenUsingWriteInt_thenASCIICharacterIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.write(48);
    printWriter.close();

    assertEquals(0, outputFromPrintWriter());
}

我们将48传递给write()方法,得到输出0。查阅ASCII表,我们发现48对应的符号就是数字0。如果传入64,输出将是数字4

outputFromPrintWriter()方法简单地读取write()方法在文件中写入的内容,以便比较:

Object outputFromPrintWriter;

Object outputFromPrintWriter() {
    try (BufferedReader br = new BufferedReader(new FileReader("output.txt"))){
        outputFromPrintWriter = br.readLine();
    } catch (IOException e){
        e.printStackTrace();
        Assertions.fail();
    }
    return outputFromPrintWriter;
}

接下来,看看write(char[] buf, int off, int len)版本,它会写入数组的一部分,从指定起始位置到给定长度:

@Test
void whenUsingWriteCharArrayFromOffset_thenCharArrayIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.write(new char[]{'A','/','&','4','E'}, 1, 4);
    printWriter.close();

    assertEquals("/&4E", outputFromPrintWriter());
}

测试显示,write()方法从我们指定的偏移量开始,打印了数组中的四个字符到output.txt文件。

再来看看write(String s, int off, int len)的第二个版本,它从指定位置写入字符串的部分内容:

@Test
void whenUsingWriteStringFromOffset_thenLengthOfStringIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.write("StringExample", 6, 7 );
    printWriter.close();

    assertEquals("Example", outputFromPrintWriter());
}

3. PrintWriter.print()方法

print()方法有九种重载形式,可以接受布尔值、字符、字符数组、双精度数、浮点数、整数、长整型、对象和字符串等类型。

print()方法的行为在所有变体中类似。除了Stringchar类型,其他类型的参数都会被String.valueOf()方法转换成字符串,然后根据平台默认字符编码转换为字节,并以与write(int)相同的方式写入。

首先,看print(boolean b)版本:

@Test
void whenUsingPrintBoolean_thenStringValueIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.print(true);
    printWriter.close();

    assertEquals("true", outputFromPrintWriter());
}

接着是print(char c)

@Test
void whenUsingPrintChar_thenCharIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.print('A');
    printWriter.close();

    assertEquals("A", outputFromPrintWriter());
}

print(int i)的效果如下:

@Test
void whenUsingPrintInt_thenValueOfIntIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.print(420);
    printWriter.close();

    assertEquals("420", outputFromPrintWriter());
}

print(String s)的输出如下:

@Test
void whenUsingPrintString_thenStringIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    printWriter.print("RandomString");
    printWriter.close();

    assertEquals("RandomString", outputFromPrintWriter());
}

对于print(Object obj)的测试:

@Test
void whenUsingPrintObject_thenObjectToStringIsPrinted() throws FileNotFoundException {

    PrintWriter printWriter = new PrintWriter("output.txt");

    Map example = new HashMap();

    printWriter.print(example);
    printWriter.close();

    assertEquals(example.toString(), outputFromPrintWriter());
}

如上例所示,调用print()方法并传递一个对象作为参数,会打印该对象的toString()表示形式。

4. write()print()方法的差异

两个方法的主要区别在于细节处理。

  • write(int)仅写入一个字符,输出对应于传递参数的ASCII符号。
  • print(*)方法(除了Stringchar)将charint等类型的参数转换为String,通过String.valueOf(*)。这个String按照平台默认字符编码转换为字节,并像write(int)一样写入。

print()方法不同,write()方法只处理单个字符、字符串和字符数组。print()方法可以处理更多类型的参数,通过String.valueOf()将它们转换为可打印的字符字符串。

5. 总结

在这篇教程中,我们探讨了PrintWriter类及其write()print()方法。PrintWriter提供了多种方法帮助我们输出数据。write()方法直接打印传递的字符,而print()方法负责转换输出。

代码示例可在GitHub上查看。