[二十四]JavaIO之PrintWriter


 

功能簡介

 
PrintWriter   向文本輸出流打印對象的格式化表示形式
他與PrintStream的邏輯上功能目的是相同的--他們都想做同一件事情--更便捷的格式化打印輸出
 
PrintWriter實現了PrintStream 中的所有 print 方法,除了那些用於寫入原始字節的方法,對於那些字節,程序應該使用未編碼的字節流進行寫入
PrintStream會在換行符時自動調用自動刷新
PrintWriter在這一點上與PrintWriter不同,
只有在調用 println、printf 或 format 的其中一個方法時才可能完成此操作
類似,PrintStream   此類中的方法不會拋出 I/O 異常,可以通過 checkError() 檢查是否出現錯誤
 
PrintWriter也是裝飾器模式
只不過看起來沒那么典型而已
他直接繼承Writer   省略了抽象裝飾器角色Decorator
PrintWriter 既充當了Decorator也是一個ConcreteDecorator
它內部包含了一個Writer out
image_5b9b0ccf_7e75
 
 

構造方法

 
他內部有一個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
編碼如果不設置,那么是系統默認
 
最根本的構造方法是
image_5b9b0ccf_47a0
最根本的為什么沒有字符編碼相關的?
其實, 還有一個私有的
私有的構造方法,將帶有字符編碼情況的進行了二次的包裝
在創建 OutputStreamWriter時使用
私有的構造方法還是繞回去到上面說的這個根本的構造方法去了
image_5b9b0ccf_4548
你會從構造方法中可以看得出來
如果構造方法中指定了編碼
將會經由這個私有的構造方法轉發下

如果沒指定將會使用我們上面說的那個最根本的形式
    public PrintWriter(Writer out,
                       boolean autoFlush) {
不指定編碼的 
全部都是使用
PrintWriter(Writer out, boolean autoFlush)
image_5b9b0ccf_1287
帶編碼的借助於私有構造方法進行請求轉發
private PrintWriter(Charset charset, File file)
image_5b9b0ccf_2318
說了那么多,其實也只還是需要記住下面這一個就好了
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 的狀態 
image_5b9b0cd0_67a9
image_5b9b0cd0_5996
 
 

print(xxx) /println(xxx)

println()
通過寫入行分隔符字符串終止當前行。行分隔符字符串由系統屬性 line.separator 定義,不一定是單個換行符 ('\n')
image_5b9b0cd0_1da5
 
print(boolean)
image_5b9b0cd0_39e9 + println()  = println(boolean)
print(char)
image_5b9b0cd0_49f5 + println()  = println(char)
print(int)
image_5b9b0cd0_278d + println()  = println(int)
print(long)
image_5b9b0cd0_72bd + println()  = println(long)
print(float)
image_5b9b0cd0_2f17 + println()  = println(float)
print(double)
image_5b9b0cd0_38b7 + println()  = println(double)
print(char[])
image_5b9b0cd0_567e + println()  = println(char[])
print(String)
image_5b9b0cd0_2925 + println()  = println(String)
print(Object) image_5b9b0cd0_5968 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方法
image_5b9b0cd0_b67
 
 

printf 與 format

PrintWriter內部也有一個Formatter
image_5b9b0cd0_3ac3
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
image_5b9b0cd0_7395
jdk1.8中 format方法與PrintStream 中幾乎一樣的,幾乎一樣的,幾乎一樣的....
 
 
PrintWriter提供了close以及flush方法
如下圖所示,依賴於內部out 的 close和flush 也沒什么好說的
image_5b9b0cd0_6f9e
 

總結

 
PrintWriter 構造方法很多,提供出來的方法也很多,看起來讓人眼花繚亂
其實他就是一個裝飾工具類,底層邏輯也很簡單
既然是工具性質的
1. 自然需要有足夠便捷的構造形式,你看那么多構造方法,最終不過也就是一種形式的構造方法
2. 自然有能夠有多變的輸出形式才能夠說是便捷的輸出打印嘛
對於Writer家族的一些基本操作,基本上是沿用了Write
 
所謂的增加的便捷亮點各種print和println
也就只是使用Writer本身的write方法打印輸出他們的字符 形式
轉換為字符的規則為:
基本數據類型和Object 會使用String.valueOf進行轉換  
字符 字符數組 String本身就是字符/字符串的形式
 
另外的一個亮點是printf 同PrintStream中的是一樣的,想要弄清楚重點在於弄清楚 Formatter了
 
上面說了,他既然是裝飾工具流,所以說他必然要依賴於其他的輸出流
PrintWriter就是依賴Writer,他就是來給這個Writer增加更便捷的打印輸出功能的
既然着重點在於格式化輸出數據,那么他的關注點自然在於數據的形式,而不是在於怎么寫,所以write方法都幾乎不動使用的還是原來的
然后在實際的調用各種print方法的時候,在對方法的入參進行轉換,換成了字符的形式而已
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM