[二十四]JavaIO之PrintWriter

功能简介

PrintWriter   向文本输出流打印对象的格式化表示形式

他与PrintStream的逻辑上功能目的是相同的--他们都想做同一件事情--更便捷的格式化打印输出

PrintWriter实现了PrintStream 中的所有 print 方法,除了那些用于写入原始字节的方法,对于那些字节,程序应该使用未编码的字节流进行写入

PrintStream会在换行符时自动调用自动刷新 PrintWriter在这一点上与PrintWriter不同, 只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作

类似,PrintStream   此类中的方法不会抛出 I/O 异常,可以通过 checkError() 检查是否出现错误

PrintWriter也是装饰器模式只不过看起来没那么典型而已他直接继承Writer   省略了抽象装饰器角色DecoratorPrintWriter 既充当了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,然后调用writeString 如果是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借助于formatformat依赖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方法的时候,在对方法的入参进行转换,换成了字符的形式而已

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Kotlin 函数式编程之 Lambda 与 高阶函数《Kotlin 极简教程》Kotlin 开发者社区

1053
来自专栏C语言及其他语言

【优秀题解】问题 1113: C语言考试练习题_保留字母

斐波纳契数列 1,1,2,3,5,8,13,21,34,55,89……这个数列则称为“斐波纳契数列”,其中每个数字都是“斐波纳契数”。

1073
来自专栏一个会写诗的程序员的博客

第6章 扩展函数与属性第6章 扩展函数与属性

在使用Java的时候,我们经常使用诸如StringUtil, DateUtil等等一堆工具类,代码写起来也比较冗长。举个例子,获取一个字符串的第一个字符值、最后...

712
来自专栏Java大联盟

EL表达式详解

如果不实用EL表达式,JSP页面获取后台传来的数据,需要通过Java脚本的方式获取:

1232
来自专栏向治洪

Kotlin 是如何避免空指针问题的

在谈Kotlin的优势的时候,大家都会想到空指针安全这一点,那么Kotlin又是如何避免这些问题的呢?下面从Kotlin的一些语法规则上给出介绍。 可空类型 默...

2847
来自专栏java闲聊

JDK8-Lambda表达式集合操作

public static List<Dish> toLists(){ return Arrays.asList( new...

993
来自专栏10km的专栏

fastjson:javabean按字段(field)序列化存储为Map并反序列化

大部分json工具对java对象整体序列化都提供了简单的调用方式,以fastjson为例: Model model = new Model(); String ...

3645
来自专栏Android Note

介绍Kotlin第二部分(翻译篇)

1474
来自专栏码神联盟

面试题 | 《Java面试题集》 -- 第二套

start()用来启动一个线程,当调用start方法后,系统才会开启一个新的线程,进而调用run()方法来执行任务,而单独的调用run()就跟调用普通方法是一样...

1112
来自专栏Golang语言社区

package reflect

reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函...

1283

扫码关注云+社区

领取腾讯云代金券