美文网首页
【Java】小议PrintStream和PrintWriter

【Java】小议PrintStream和PrintWriter

作者: 老九君 | 来源:发表于2019-08-09 10:34 被阅读0次

今天我们来简单了解下PrintStream和PrintWriter这两个类的几点区别:

区别一:

PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。

Java的一个字符(char)是16bit的,一个byte是8bit的。PrintStream是写入一串8bit的数据的,PrintWriter是写入一串16bit的数据的。String缺省是用UNICODE编码,是16bit的。因此用PrintWriter写入的字符串,跨平台性会好一些,PrintStream的可能会出现字符集乱码。

PrintStream是用来操作byte,PrintWriter是用来操作Unicode,一般需要处理中文时用PrintWriter好了。

Stream用于二进制文件(非文本) ,Writer/Reader用于文本文件(虽然也是二进制,不过是按照一定的字符编码规则,不像前者) ,当然Stream也可用于文本,只不过比Writer/Reader来的麻烦,PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。

区别2:

Java输出流中的PrintStream和PrintWriter有什么区别,其实很多场合都能混用。比如用于网络间通信,发送消息时,可用PrintStream也可用PrintWriter:

Socket client;

PrintStream output = new PrintStream(client.getOutputStream());

output.println("aaa");

output.flush();

把上例中的PrintStream换成PrintWriter效果是一样的。Java I/O流分为两类,字节流和字符流。字节流是指InputStream/OutputStream及其子类,字符流是指Reader/Writer及其子类。

PrintStream是OutputStream的子类,PrintWriter是Writer的子类,两者处于对等的位置上,所以它们的API是非常相似的。PrintWriter实现了Writer的所有print方法。对于PrintStream,所有println方法都在内部调用相应的print方法,比如println(char x)的方法体就是调用print(x),再写入一个平台相关的换行符。PrintStream构建时会在内部new一个BufferedWriter,所有print方法都在内部调用这个Writer的write方法(write(String)或write(char[])),对于print(char[]),直接调用write(char[])。对于其他的print方法,先用String.valueOf获得参数的字符串表示,然后调用write(String)。

对于PrintWriter,所有println方法也都在内部调用print方法,然后再调用一个没有参数的println()来换行,print方法调用write方法。传入OutputStream时,PrintWriter会在内部构造一个BufferedWriter;而传入Writer时,PrintStream内部直接使用该Writer,此时PrintWriter是否进行了缓冲全看该Writer。

所以,对于使用print系列方法的场合,二者没什么区别。但是,PrintStream是字节流,它有处理raw byte的方法,write(int)和write(byte[],int,int);PrintWriter是字符流,它没有处理raw byte的方法。PrintStream和PrintWriter的auto flushing机制有点不同,前者在输出byte数组、调用println方法、输出换行符或者byte值10(即\n)时自动调用flush方法,后者仅在调用println方法时发生auto flushing。

区别3:

PrintStream类是过滤器类中一个不可忽视的成员,最基本的标准输出就要借助于它——我们常用的System.out变量就是PrintStream实例。与之对应的字符流类是PrintWriter类。 PrintStream有两个构造函数(在新版API中已标记为过时):

■public PrintStream(OutputStream out)

■public PrintStream(OutputStream out,boolean autoFlush)

其中,autoFlush置为true时,每当输出遇到换行符,缓冲区的内容就被强制全部输出,如同调用了一次flush()。但要注意,如果没遇到换行符,还是会有数据“卡”在缓冲区里。 有如下几个方法:

■public void write(int b)

■public void write(byte b,int offset,int length)

■public void flush()

■public void close()

■public void print(Object obj)

此外print()方法有许多重载形式,即有多种参数。它们是字符串(String)、字符数组 (char[])、字符(char)、整数(int)、长整数(long)、浮点数(float)、双精度浮点数(double)、布尔值 (boolean)。其中,输出多个数单位的print()方法(也就是指参数为String和char[]的)是同步(synchronized)方法。

■public void println()输出一个换行符。

■public synchronized void println(Object obj)

println()方法有9个重载形式,几乎就是print()方法的翻版。唯一的区别在于println()方法都是同步的。

■public boolean checkError()

检查输出过程中有什么错误,如有,返回true值。只要输出流中出现一次错误,则出错后的任意对checkError()的调用均会返回真值。

        PrintWriter类是JDK1.1版增加了与字节流I/O相对应的字符流I/O。但是,为了保持兼容性,原先的类几乎没有改动。再加之调试的需要,PrintStream类被保留,并且System类中的成员变量out、err仍作为它的对象。然而,PrintWriter用于大多数输出比PrintStream更为合适。因此1.1版的API中建议新开发的代码使用PrintWriter类,并将PrintStream类的两个构造函数标记为过时。这样,虽然使用System.out输出不会产生问题,在程序中创建新的PrintStream对象时却会产生编译时的警告。

下面我们先来看看PrintStream(字节流)的打印实例:

PrintWriter(字符流)打印实例:

老九学堂出品,转载请私信哦

对于文章内容有不理解的可以添加老九君个人QQ:614940318,请备注来自简书

老九学堂免费C、C++、Java课程地址:

https://study.163.com/courses-search?keyword=%E8%80%81%E4%B9%9D%E5%AD%A6%E5%A0%82

相关文章

网友评论

      本文标题:【Java】小议PrintStream和PrintWriter

      本文链接:https://www.haomeiwen.com/subject/vlscjctx.html