[二十四]JavaIO之PrintWriter
程序员文章站
2022-07-10 11:15:23
深入浅出的解析PrintWriter,对他的设计逻辑,使用方法,print /println printf进行了简单的介绍 ......
功能简介
printwriter 向文本输出流打印对象的格式化表示形式
他与printstream的逻辑上功能目的是相同的--他们都想做同一件事情--更便捷的格式化打印输出
printwriter实现了printstream 中的所有 print 方法,除了那些用于写入原始字节的方法,对于那些字节,程序应该使用未编码的字节流进行写入 |
printstream会在换行符时自动调用自动刷新
printwriter在这一点上与printwriter不同,
只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作
|
类似,printstream 此类中的方法不会抛出 i/o 异常,可以通过 checkerror() 检查是否出现错误 |
printwriter也是装饰器模式 只不过看起来没那么典型而已 他直接继承writer 省略了抽象装饰器角色decorator printwriter 既充当了decorator也是一个concretedecorator 它内部包含了一个writer out |
构造方法
他内部有一个writer out ,而且刚才我们已经说了他是装饰器模式
所以他必然会需要一个out,你从构造方法的实际情况也可以看得出来
构造方法主要内容包括下面三部分:
1. 首先需要一个writer
2. 自动刷新的标志
3. 字符编码的设置
|
对于一个writer
1. 他要么就是一个直接的writer
2. 要么是一个new outputstreamwriter( outputstream) 把outputstream转换为writer
3. 另外,通过file或者string路径名,也可以构造fileoutputstream ,他就是一个outputstream,也就是下面的形式:
new outputstreamwriter( new fileoutputstream(file/string路径) )
|
自动刷新,如果不传递,默认false 编码如果不设置,那么是系统默认 |
最根本的构造方法是 |
最根本的为什么没有字符编码相关的? 其实, 还有一个私有的 私有的构造方法,将带有字符编码情况的进行了二次的包装 在创建 outputstreamwriter时使用 私有的构造方法还是绕回去到上面说的这个根本的构造方法去了 |
你会从构造方法中可以看得出来 如果构造方法中指定了编码 将会经由这个私有的构造方法转发下 如果没指定将会使用我们上面说的那个最根本的形式 public printwriter(writer out,
boolean autoflush) {
|
不指定编码的 全部都是使用printwriter(writer out, boolean autoflush) |
带编码的借助于私有构造方法进行请求转发 private printwriter(charset charset, file file) |
说了那么多,其实也只还是需要记住下面这一个就好了 printwriter(writer out, boolean autoflush) 只有file参数或者string路径参数 才会设置编码的参数, 如果设置了编码的参数的话,将会在把他们转换为writer时, 也就是 new outputstreamwriter 中通过指定编码参数构造 |
write方法
write方法的本质还是将数据写入到输出流 提供了5个版本的write |
void write(char[] buf)
将字符数组 写入
void write(char[] buf, int off, int len)
将字符数组的某一部分 写入
void write(int c)
将单个字符 写入
void write(string s)
将字符串 写入
void write(string s, int off, int len)
将字符串的某一部分 写入
|
三个基础方法,两个简化版方法
看得出来,类似printstream printwriter 也不会抛出ioexception异常
可以通过 checkerror 方法查看 trouble 的状态
|
print(xxx) /println(xxx)
println() 通过写入行分隔符字符串终止当前行。行分隔符字符串由系统属性 line.separator 定义,不一定是单个换行符 ('\n') |
print(boolean)
|
+ println() = println(boolean) | |
print(char)
|
+ println() = println(char) | |
print(int)
|
+ println() = println(int) | |
print(long)
|
+ println() = println(long) | |
print(float)
|
+ println() = println(float) | |
print(double)
|
+ println() = println(double) | |
print(char[])
|
+ println() = println(char[]) | |
print(string)
|
+ println() = println(string) | |
print(object) |
println(string.valueof(object))+ println() = println(object) 稍微特殊,先转换为string string.valueof(object) 然后print(string)+ println() |
可以看得出来 print系列都是调用的write方法 而且,基本上是write(string s)方法 boolean 会翻译成 字符串 true 或者false,然后调用write string 如果是null 翻译成字符串 null 然后调用write 除了object略微特殊以外,其他所有的print 和 println结合之后可以产生对应的println(xxx)的形式 |
append
三个版本的append方法 append(char)
append(java.lang.charsequence)
append(java.lang.charsequence, int, int)
内部全部都是依赖于write方法
|
printf 与 format
printwriter内部也有一个formatter |
printf(java.util.locale, java.lang.string, java.lang.object...)
printf(java.lang.string, java.lang.object...)
format(java.util.locale, java.lang.string, java.lang.object...)
format(java.lang.string, java.lang.object...)
|
printf借助于format format依赖formatter |
jdk1.8中 format方法与printstream 中几乎一样的,几乎一样的,几乎一样的.... |
printwriter提供了close以及flush方法 如下图所示,依赖于内部out 的 close和flush 也没什么好说的 |
总结
printwriter 构造方法很多,提供出来的方法也很多,看起来让人眼花缭乱
其实他就是一个装饰工具类,底层逻辑也很简单
既然是工具性质的
1. 自然需要有足够便捷的构造形式,你看那么多构造方法,最终不过也就是一种形式的构造方法
2. 自然有能够有多变的输出形式才能够说是便捷的输出打印嘛
对于writer家族的一些基本操作,基本上是沿用了write
所谓的增加的便捷亮点各种print和println
也就只是使用writer本身的write方法打印输出他们的字符 形式
转换为字符的规则为:
基本数据类型和object 会使用string.valueof进行转换 |
字符 字符数组 string本身就是字符/字符串的形式 |
另外的一个亮点是printf 同printstream中的是一样的,想要弄清楚重点在于弄清楚 formatter了
上面说了,他既然是装饰工具流,所以说他必然要依赖于其他的输出流
printwriter就是依赖writer,他就是来给这个writer增加更便捷的打印输出功能的
既然着重点在于格式化输出数据,那么他的关注点自然在于数据的形式,而不是在于怎么写,所以write方法都几乎不动使用的还是原来的
然后在实际的调用各种print方法的时候,在对方法的入参进行转换,换成了字符的形式而已
下一篇: 30个精简代码的小技巧(第11-20个)