本文主要介绍PrintStream和PrintWriter的区别和联系。通过示例代码进行了非常详细的介绍,对于大家的学习或者工作都有一定的参考价值。有需要的朋友下面和边肖一起学习。
前言
在将一个字符串写入文件时,两者最终都需要通过字符集的映射关系得到对应的字节。
但是char获取对应字节的时机不一样,有new printstream(新缓冲输出流(新文件输出流(' basicfile output . out '));而new printwriter(new buffer writer(' basicfile output . out ')),比如前者从PrintStream到BufferedOutputStream存储一个字符串的时候就已经是一个字节了;当后者存储字符串时,它不会将字符转换为字节,直到FileWriter实际写入文件。
如果PrintStream设置为autoFlush,那么Flush方法将在以下情况下自动执行:写入字节数组、调用println的任何重载版本、写入换行符(char)以及写入换行符(\n)的字节存储。
如果PrintWriter设置为autoFlush,那么在以下情况下将自动执行Flush方法:调用println、printf和format方法。
它们都不会抛出IO异常,因为它们是在方法内部被捕获的,是否发生异常可以通过checkError()来判断。
PrintWriter将使用特定于平台的换行符(如Windows和linux),而PrintStream将是固定的。
总的来说,Reader/Writer相对于InputStream/OutputStream来说是一个升级,优化了一开始设计的不太好的地方。
二者的构造器分析
两者真的很像。你可以看看他们的api文档,发现他们的构造函数和方法几乎一模一样。
你会注意到,在PrintWriter的构造函数中也可以指定字符集,这可能有点奇怪,因为作为一个装饰用的编写器,它不应该关心字符如何对应字节,而只关心字符。
PrintWriter有两个可以指定字符集的构造函数:PrintWriter(File file,StringCSN)和PrintWriter (StringFileName,String csn),但是这两个构造函数最终都会调用下面的构造函数。可以看出,charset用于装饰器最内层的FileOutputStream,而外层的两个Writer则不必关心。这说明Writer真的不需要关心字符集。
/*私有构造函数*/
私有PrintWriter(Charset charset,File file)
引发FileNotFoundException
{
this(new buffered writer(new output streamwriter(new file output stream(file),charset)),
假);
}
其实PrintStream也很低。观察它的构造函数可以发现,它其实是由BufferedWriter驱动的(这个看起来像上面贴的PrintWriter的构造函数中的逻辑,这里指的是装饰器的装饰过程):
/*私有构造函数*/
私有打印流(布尔自动刷新,输出流输出){
超(出);
this.autoFlush=autoFlush
this . charout=new output streamwriter(this);//给自己装饰一层
this . textout=new buffered writer(charOut);//用另一层装饰自己
}
私有void写入(字符串){
尝试{
同步(这){
ensure open();
textOut.write//首先调用最外层流的write函数
textout . flush buffer();
charout . flush buffer();
if (autoFlush (s.indexOf('\n')=0))
out . flush();
}
}
.
}
也就是说这个新的printstream(新的缓冲输出流(新的fileoutput流(' basicfile output . out '));事实上,将生成五个流对象(装饰器模式将有五层,禁止玩偶嵌套!)。看写函数。每写一个字符串,实际上都是通过装饰器最外层的BufferedWriter来写,然后执行BufferedWriter和OutputStreamWriter的flushBuffer函数,把字符转换成字节(像挤牙膏一样,只不过是从外向内挤),把字节做成这个对象。
三种类型的PrintStream (File、OutputStream和String)的构造函数都可以有字符集。
我们只看一个带字符集的构造函数,发现字符集设置在this的外层,所以当字节数组通过OutputStreamWriter传递给this时,字节数组已经通过了特定字符集charset的编码:
private PrintStream(boolean autoFlush,OutputStream out,Charset charset) {
超(出);
this.autoFlush=autoFlush
this . charout=new output streamwriter(this,charset);
this . textout=new buffered writer(charOut);
}
与PrintStream相比,PrintWriter多了一种类型的构造函数(File、OutputStream、String、Writer),即它也可以接受一个Writer。
二者的方法分析
对比两个方法的api文档,你会发现前面的方法签名是一样的,只是后面的write方法不同,所以我们只看不同的部分。相同的部分占大多数,同学们可以自己查一下。
PrintStream的write方法们
从方法的描述中也可以看出,这些写方法都是针对byte或者byte[]的。
发现一个写方法是继承自FilterOutputStream的,因为这个重载版本的写方法PrintStream并没有覆盖父方法(下面两个是覆盖FilterOutputStream的)。
FilterOutputStream的写入(byte[] b)版本如下:
PrintWriter的write方法们
从方法的描述中也可以看出,这些写方法是针对char或者string的。
关于PrintStream和PrintWriter的区别和联系的这篇文章到此为止。有关PrintStream和PrintWriter之间的差异的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。