Java IO:PrintStream、PrintWriter 打印流

虽然像FileOutputStream、OutputStreamWriter这些输出流可以输出信息,但是其会要求把数据先处理为字符串或字节数组,使用不便。为此在Java IO体系专门提供了两个打印流——PrintStream 字节打印流 、PrintWriter 字符打印流。二者均重载了print、printf 等函数,方便开发者直接输出打印其它类型的数据

abstract.jpeg

PrintStream 字节打印流

PrintStream其支持多种构造方式,如下所示。值得一提的是PrintStream是对字节输出流的包装,所以即使是从文件中直接创建字节打印流,其构造方法内部也是先构造一个FileOutputStream字节输出流

1
2
3
4
5
6
7
8
9
10
11
12
public class PrintStream extends FilterOutputStream {
...
// 从文件直接创建字节打印流
public PrintStream(File file) throws FileNotFoundException;
// 从文件直接创建字节打印流
public PrintStream(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException;
// 从字节输出流创建字节打印流
public PrintStream(OutputStream out);
// 从文件直接创建字节打印流
public PrintStream(String fileName) throws FileNotFoundException;
...
}

这里一个实例来演示如何通过 PrintStream 字节打印流来直接输出数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

// 字节打印流 测试用例
public static void testPrintStream() throws FileNotFoundException, UnsupportedEncodingException {
String file1 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintStreamTest\\w1.txt";
String file2 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintStreamTest\\w2.txt";
String file3 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintStreamTest\\w3.txt";

// 从字节流中创建字节打印流
FileOutputStream out = new FileOutputStream(file1);
PrintStream printStream1 = new PrintStream(out, true, "gbk");
getList().forEach( e -> {
String separator = " : ";
printStream1.print(e.getName());
printStream1.print(separator);
printStream1.print(e.getAge());
printStream1.print(separator);
printStream1.println(e.getSalary());
});
printStream1.flush();
printStream1.close();

// 直接从文件中创建字符打印流
PrintStream printStream2 = new PrintStream(file2,"gbk");
getList().forEach( e ->{
String separator = " | ";
printStream2.print(e.getName());
printStream2.print(separator);
printStream2.print(e.getAge());
printStream2.print(separator);
printStream2.println(e.getSalary());
});
printStream2.flush();
printStream2.close();

// 直接从文件中创建字符打印流
PrintStream printStream3 = new PrintStream(file3, "gbk");
getList().forEach( e -> // 格式化输出
printStream3.printf("Name: %s\tAge: %d\tSalary: %.2f\n",
e.getName(), e.getAge(), e.getSalary())
);
printStream3.flush();
printStream3.close();
}

// 构造一个 Employee 的列表 作为 数据来源
public static List<Employee> getList() {
Employee e1 = Employee.builder()
.name("Aaron")
.age(23)
.salary(1000.00)
.build();

Employee e2 = Employee.builder()
.name("Tony")
.age(13)
.salary(20.00)
.build();

Employee e3 = Employee.builder()
.name("David")
.age(36)
.salary(300.00)
.build();

Employee e4 = Employee.builder()
.name("艾米")
.age(46)
.salary(1300.00)
.build();


List<Employee> list = new LinkedList<>();
list.add(e1);
list.add(e2);
list.add(e3);
list.add(e4);
return list;
}

从下面的测试结果可以看出,我们不仅可以通过 print、println 方法直接输出打印其它类型的数据,还可以通过printf实现格式化输出

figure 1.jpeg

PrintWriter 字符打印流

同样地,PrintWriter 也是对字符输出流的包装,所以虽然其构造函数支持从文件、字节输入流中构造,但是构造函数内部均先构造了一个BufferedWriter实例

1
2
3
4
5
6
7
8
9
public class PrintWriter extends Writer {
...
public PrintWriter(File file) throws FileNotFoundException;
public PrintWriter(File file, String csn)
public PrintWriter(String fileName) throws FileNotFoundException;
public PrintWriter(OutputStream out);
public PrintWriter (Writer out);
...
}

这里一个实例来演示如何通过 PrintWriter 字符打印流来直接输出数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void testPrintWriter() throws FileNotFoundException, UnsupportedEncodingException {
String file1 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintWriterTest\\w1.txt";
String file2 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintWriterTest\\w2.txt";
String file3 = "E:\\TestCode\\JavaTest\\src\\main\\resources\\PrintWriterTest\\w3.txt";


// 直接从文件中创建字符打印流
PrintWriter printWriter1 = new PrintWriter(file1,"gbk");
getList().forEach( e -> {
String separator = " - ";
printWriter1.print(e.getName());
printWriter1.print(separator);
printWriter1.print(e.getAge());
printWriter1.print(separator);
printWriter1.println(e.getSalary());
});
printWriter1.flush();
printWriter1.close();

// 从字节流中创建字符打印流
FileOutputStream fileOutputStream2 = new FileOutputStream(file2);
PrintWriter printWriter2 = new PrintWriter(fileOutputStream2);
getList().forEach( e -> {
String separator = " % ";
printWriter2.print(e.getName());
printWriter2.print(separator);
printWriter2.print(e.getAge());
printWriter2.print(separator);
printWriter2.println(e.getSalary());
});
printWriter2.flush();
printWriter2.close();

// 从字符流中创建字符打印流
FileOutputStream fileOutputStream3 = new FileOutputStream(file3);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream3, "gbk");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
PrintWriter printWriter3 = new PrintWriter(bufferedWriter);
getList().forEach( e ->
printWriter3.printf("Name: %s\tAge: %d\tSalary: %.2f\n",
e.getName(), e.getAge(), e.getSalary())
);
printWriter3.flush();
printWriter3.close();
}

可以看出,PrintWriter 与 PrintStream 相比,在输出打印的使用上,并无明显区别

figure 2.jpeg

System.out.println

我们在日常开发经常会用 System.out.println 来向控制台打印输出信息,其实 out 就是System类中一个PrintStream类型的静态成员变量

figure 3.jpeg

参考文献

  1. Java核心技术·卷II 凯.S.霍斯特曼著
0%