日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Java IO流之PrintStream分析

發布時間:2025/3/12 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java IO流之PrintStream分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

PrintStream繼承了FilterOutputStream.是"裝飾類"的一種,所以屬于字節流體系中(與PrintStream相似的流PrintWriter繼承于Writer,屬于字符流體系中),為其他的輸出流添加功能.使它們能夠方便打印各種數據值的表示形式.此外,值得注意的是:

  • 與其他流不同的是,PrintStream流永遠不會拋出異常.因為做了try{}catch(){}會將異常捕獲,出現異常情況會在內部設置標識,通過checkError()獲取此標識.
  • PrintStream流有自動刷新機制,例如當向PrintStream流中寫入一個字節數組后自動調用flush()方法.

PrintStream流打印的字符通過平臺默認的編碼方式轉換成字節,在寫入的是字符,而不是字節的情況下,應該使用PrintWriter.PrintStream流中基本所有的print(Object obj)重載方法和println(Object obj)重載方法都是通過將對應數據先轉換成字符串,然后調用write()方法寫到底層輸出流中.常見用到PrintStream流:System.out就被包裝成PrintStream流,System.err也是PrintStream流,注意System.in不是PrintStream,是沒有包裝過的OutputStream.所以System.in不能直接使用.

PrintStream流不是直接將數據寫到文件的流,需要傳入底層輸出流out,而且要實現指定編碼方式,需要中間流OutputStreamWriter,OutputStreamWriter流實現了字符流以指定編碼方式轉換成字節流.此外為了提高寫入文件的效率,使用到了字符緩沖流BufferWriter.寫入PrintStream流的數據怎么寫到文件中.需要先了解一下數據讀取和寫入的流程.

1.數據從流寫到文件過程

輸出流----->緩沖流----->轉化流----->文件流------>文件.

2.數據從文件到流的過程

文件----->文件流----->轉化流----->緩沖流----->輸入流.

那么從PrintStream流寫到文件的過程是:

PrintStream介紹

1.構造方法

public PrintStream(OutputStream out) {} public PrintStream(OutputStream out, boolean autoFlush) {} public PrintStream(OutputStream out, boolean autoFlush, String encoding){} public PrintStream(String fileName) {} public PrintStream(String fileName, String csn){} public PrintStream(File file){} public PrintStream(File file, String csn){}
  • 創建了默認編碼方式的PrintStream流,字節輸出流out作為PrintStream流的輸出流,不自動刷新.
  • 創建默認編碼方式的PrintStream流,字節輸出流out作為PrintStream流的輸出流,傳入是否自動刷新的參數autoFlush.
  • 創建了指定編碼名稱encoding的PrintStream,字節輸出流out作為PrintStream流的輸出流.傳入是否自動刷新的參數autoFlush.
  • 創建了指定文件名稱,默認字符編碼方式的PrintStream流,FileOutputStream流作為PrintStream流的輸出流.不自動刷新.
  • 創建指定了文件名稱和字符編碼名稱csn的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新.
  • 創建指定文件對象File和默認編碼方式的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新.
  • 創建指定文件對象File和編碼名稱csn的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新.

2.內部變量

private final boolean autoFlush; private boolean trouble = false; private Formatter formatter; private BufferedWriter textOut; private OutputStreamWriter charOut;
  • autoFlush----是否自動刷新緩沖區.
  • trouble----是否拋出異常的內部標識.當PrintStream流內部拋出異常時會捕獲異常,然后將trouble的值設置成true.
  • formatter----用于數據格式化的對象Formatter.
  • textOut,charOut----PrintStream流本身不具備指定編碼功能,BufferedWriter提供了緩沖數據的功能,而OutputStreamWriter提供了按照指定編碼方法將字符轉化成字節的功能.

3.內部方法.

public void flush() {} public void close() {} public boolean checkError(){} public void write(int b){} public void write(byte buf[], int off, int len){} public PrintStream printf(String format, Object ... args){} public PrintStream printf(Locale l, String format, Object ... args){} public PrintStream format(String format, Object ... args){} public PrintStream format(Locale l, String format, Object ... args){} public PrintStream append(CharSequence csq){} public PrintStream append(CharSequence csq, int start, int end){} public PrintStream append(char c){} public void print(boolean b){} public void print(char c) {} public void print(int i) {} public void print(long l) {} public void print(float f) {} public void print(double d) {} public void print(char s[]) {} public void print(String s) {} public void print(Object obj) {} public void println() {} public void println(boolean x) {} public void println(char x){} public void println(int x) {} public void println(long x) {} public void println(float x) {} public void println(double x) {} public void println(char x[]) {} public void println(String x) {} public void println(Object x) {}
  • flush()----刷新流,將緩沖的數據寫到底層輸出流中.
  • close()—關閉流,釋放關聯的資源.
  • checkError()—檢查流中異常狀態,如果PrintStream流中有異常拋出,返回true.
  • write(int b)----將單個字節b寫到PrintStream流中.
  • write(byte buf[] ,int off,int len)----將字節數組buf中off位置開始,len個字節寫到PrintStream流中.
  • printf(String format, Object … args)----將數據args按照默認的Locale值和format格式進行格式化后寫到PrintStream流中,方法執行等同于out.format(format, args)
  • printf(Locale l, String format, Object … args)----將數據args根據Locale值和format格式進行格式化后寫到PrintStream輸出流中,方法執行等同于out.printf(l, format,args).
  • format(String format, Object … args)----根據默認的Locale值和format格式來格式化數據args.
  • format(Locale l, String format, Object … args)----將數據args根據Locale值和format格式進行格式化.
  • append(CharSequence csq, int start, int end)----將字符序列csq中start(包含)位置到end(不包含)之間的子字符序列添加到PrintStream輸出流中,此方法執行等同于out.print(csq.subSequence(start, end).toString()).
  • append(char c)----將單個字符添加到PrintStream輸出流中.此方法執行等同于out.print?.

其他的print(Object obj)的重載方法與println(Object obj)的重載方法總結如下,兩個區別是println(Object obj)在寫完數據后,會寫入一個換行符.而這兩類方法寫入數據時都會先將數據轉成字符串,然后調用底層輸出流寫到文件中(比如boolean類型的數據true,會先轉成字符串"true").此兩類方法都將寫入數據轉化成了字符串,所以實際調用的方法是write(String s).

修飾符不寫入換行的方法寫入換行的方法(寫入數據+換行符)功能
publicvoid print(boolean b){}void println(boolean b){}將boolean類型數據對應字符串寫到PrintStream流中
publicvoid print(char c){}void println(char c){}將char類型數據對應字符串寫到PrintStream流中
publicvoid print(int i) {}void println(int i) {}將int類型數據對應字符串寫到PrintStream流中
publicvoid print(long l) {}void println(long l) {}將long類型數據對應字符串寫到PrintStream流中
publicvoid print(float f) {}void println(float f) {}將float類型數據對應字符串寫到PrintStream流中
publicvoid print(double d) {}void println(double d) {}將double類型數據對應字符串寫到PrintStream流中
publicvoid print(char s[]) {}void println(char s[]) {}將字符數組寫到PrintStream流中
publicvoid print(String s) {}void println(String s) {}將字符串s寫到PrintStream流中
publicvoid print(Object obj) {}void println(Object obj) {}將對象Obj對應字符串寫到PrintStream流中
public-void println() {}將換行符寫到PrintStream流中

PrintStream案例

public class PrintStreamDemo {public static void main(String[] args) throws IOException {final String fileName = "D:\\java.txt";File file = new File(fileName);testPrintMethod(fileName, file);testOtherMethod(fileName,file);}private static void testOtherMethod(String fileName,File file) throws IOException {PrintStream ps = new PrintStream(fileName);ps.write("helloworld".getBytes());ps.println();ps.format("文件名稱:%s", file.getName());ps.println();ps.write(0x41);ps.append("abcde");ps.close();}private static void testPrintMethod(final String fileName, File file) throws FileNotFoundException {PrintStream ps = new PrintStream(new FileOutputStream(fileName));ps.println('a');ps.println("hello");ps.println(2345);ps.print(3.1415);ps.println();//寫入換行符.ps.printf("文件名稱:%s,是否可讀:%s", file.getName(),file.canRead());ps.println();ps.close();} }

運行結果:

testPrintMethod結果:

testOtherMethod的結果:

PrintStream源碼分析

public class PrintStream extends FilterOutputStream implements Appendable, Closeable {//是否自動刷新緩沖區.private final boolean autoFlush;//是否拋出異常的內部標識.當PrintStream流內部拋出異常時會捕獲異常,然后將trouble的值設置成true.private boolean trouble = false;//用于數據格式化的對象Formatter.private Formatter formatter;//OutputStreamWriter轉化類,實現了編碼方式,將字符轉化字節.//BufferWriter實現了數據的緩沖.//輸出流out是將內存中數據寫到文件中./** 所以三個流的轉化方式,將數據寫到文件中的流程是:* 字符 緩沖 編碼成字節 字節* PrintStream---->BufferWriter--->OutputStreamWriter---->FileOutputStream---->文件.* */private BufferedWriter textOut;private OutputStreamWriter charOut;//判斷對象是否創建.private static <T> T requireNonNull(T obj, String message) {if (obj == null)throw new NullPointerException(message);return obj;}//根據字符編碼名稱返回Chatset對象.private static Charset toCharset(String csn)throws UnsupportedEncodingException{requireNonNull(csn, "charsetName");try {return Charset.forName(csn);} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {// UnsupportedEncodingException should be thrownthrow new UnsupportedEncodingException(csn);}}/*** 私有構造方法,創建的編碼方式為charset的PrintStream,輸出流out作為PrintStream流的輸出流,* 傳入是否自動刷新的參數autoFlush*/private PrintStream(boolean autoFlush, OutputStream out) {super(out);this.autoFlush = autoFlush;this.charOut = new OutputStreamWriter(this);this.textOut = new BufferedWriter(charOut);}private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {super(out);this.autoFlush = autoFlush;this.charOut = new OutputStreamWriter(this, charset);this.textOut = new BufferedWriter(charOut);}private PrintStream(boolean autoFlush, Charset charset, OutputStream out)throws UnsupportedEncodingException{this(autoFlush, out, charset);}//創建了默認編碼方式的PrintStream流,輸出流out作為PrintStream流的輸出流,不自動刷新.public PrintStream(OutputStream out) {this(out, false);}//創建默認編碼方式的PrintStream流,輸出流out作為PrintStream流的輸出流,傳入是否自動刷新的參數autoFlush.public PrintStream(OutputStream out, boolean autoFlush) {this(autoFlush, requireNonNull(out, "Null output stream"));}//創建了指定編碼方式encoding的PrintStream,輸出流out作為PrintStream流的輸出流.傳入是否自動刷新的參數autoFlush.public PrintStream(OutputStream out, boolean autoFlush, String encoding)throws UnsupportedEncodingException{this(autoFlush,requireNonNull(out, "Null output stream"),toCharset(encoding));}//創建了指定文件名稱,默認字符編碼方式的PrintStream流,FileOutputStream流作為PrintStream流的輸出流.不自動刷新public PrintStream(String fileName) throws FileNotFoundException {this(false, new FileOutputStream(fileName));}//創建指定了文件名稱和字符編碼名稱csn的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新public PrintStream(String fileName, String csn)throws FileNotFoundException, UnsupportedEncodingException{this(false, toCharset(csn), new FileOutputStream(fileName));}//創建指定文件對象File和默認編碼方式的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新.public PrintStream(File file) throws FileNotFoundException {this(false, new FileOutputStream(file));}//創建指定文件對象File和編碼名稱csn的PrintStream流,FileOutputStream作為PrintStream流的輸出流.不自動刷新.public PrintStream(File file, String csn)throws FileNotFoundException, UnsupportedEncodingException{// ensure charset is checked before the file is openedthis(false, toCharset(csn), new FileOutputStream(file));}//確保流沒有關閉.private void ensureOpen() throws IOException {if (out == null)throw new IOException("Stream closed");}//刷新流,調用flush()會將緩沖數據寫到底層輸出流中.public void flush() {synchronized (this) {try {ensureOpen();out.flush();}catch (IOException x) {trouble = true;}}}private boolean closing = false; /* To avoid recursive closing *///關閉流,釋放關聯資源.public void close() {synchronized (this) {if (! closing) {closing = true;try {textOut.close();out.close();}catch (IOException x) {trouble = true;}textOut = null;charOut = null;out = null;}}}//刷新流,檢查異常狀態,如果底層輸出流拋出異常,將會返回true.public boolean checkError() {if (out != null)flush();if (out instanceof java.io.PrintStream) {PrintStream ps = (PrintStream) out;return ps.checkError();}return trouble;}//設置流的異常狀態.protected void setError() {trouble = true;}//清除流的異常狀態protected void clearError() {trouble = false;}//將單個字節b寫到PrintStream流中.public void write(int b) {try {synchronized (this) {ensureOpen();out.write(b);if ((b == '\n') && autoFlush)out.flush();}}catch (InterruptedIOException x) {Thread.currentThread().interrupt();}catch (IOException x) {trouble = true;}}//將字節數組buf中off位置開始,len個字節寫到PrintStream流中.public void write(byte buf[], int off, int len) {try {synchronized (this) {ensureOpen();out.write(buf, off, len);if (autoFlush)out.flush();}}catch (InterruptedIOException x) {Thread.currentThread().interrupt();}catch (IOException x) {trouble = true;}}/**下面對于的字符操作的私有方法會時時刷新緩沖,保持跟底層輸出流一樣效率*///將字符數組buf寫到PrintStream流中.private void write(char buf[]) {try {synchronized (this) {ensureOpen();textOut.write(buf);textOut.flushBuffer();charOut.flushBuffer();if (autoFlush) {for (int i = 0; i < buf.length; i++)if (buf[i] == '\n')out.flush();}}}catch (InterruptedIOException x) {Thread.currentThread().interrupt();}catch (IOException x) {trouble = true;}}//將字符串s寫到PrintStream流中.private void write(String s) {try {synchronized (this) {ensureOpen();textOut.write(s);textOut.flushBuffer();charOut.flushBuffer();if (autoFlush && (s.indexOf('\n') >= 0))out.flush();}}catch (InterruptedIOException x) {Thread.currentThread().interrupt();}catch (IOException x) {trouble = true;}}//將換行符寫到PrintStream流中private void newLine() {try {synchronized (this) {ensureOpen();textOut.newLine();textOut.flushBuffer();charOut.flushBuffer();if (autoFlush)out.flush();}}catch (InterruptedIOException x) {Thread.currentThread().interrupt();}catch (IOException x) {trouble = true;}}//將boolean類型數據對應的字符串"true"或者"false"寫到PrintStream流中,實際調用write()方法public void print(boolean b) {write(b ? "true" : "false");}//將char類型數據對應字符串寫到PrintStream流中,實際調用write()方法public void print(char c) {write(String.valueOf(c));}//將int類型數據對應的字符串寫到PrintStream流中,實際調用write()方法.public void print(int i) {write(String.valueOf(i));}//將long類型數據對應的字符串寫到PrintStream流中,實際調用write()方法.public void print(long l) {write(String.valueOf(l));}//將float類型數據對應的字符串寫到PrintStream流中,實際調用write()方法.public void print(float f) {write(String.valueOf(f));}//將doule類型數據對應的字符串寫到PrintStream流中,實際調用write()方法.public void print(double d) {write(String.valueOf(d));}//將字符數組寫到PrintStream流中,實際調用write()方法.public void print(char s[]) {write(s);}//將字符串s寫到PrintStream流中,s為null,將會寫入"null",實際調用write()方法.public void print(String s) {if (s == null) {s = "null";}write(s);}//將對象obj對應的字符串寫到PrintStream流中,實際調用write()方法.public void print(Object obj) {write(String.valueOf(obj));}//將換行符寫到PrintStream流中.用于終止當前行(換行符由系統定義)public void println() {newLine();}//將boolean類型數據對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(boolean x) {synchronized (this) {print(x);newLine();}}//將char類型單個字符對應字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(char x) {synchronized (this) {print(x);newLine();}}//將int類型數據對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(int x) {synchronized (this) {print(x);newLine();}}//將long類型數據對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(long x) {synchronized (this) {print(x);newLine();}}//將float類型數據對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(float x) {synchronized (this) {print(x);newLine();}}//將double類型數據對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(double x) {synchronized (this) {print(x);newLine();}}//將字符數組+換行符寫到PrintStream流中,實際調用print()-->write()public void println(char x[]) {synchronized (this) {print(x);newLine();}}//將字符串+換行符寫到PrintStream流中,實際調用print()-->write()public void println(String x) {synchronized (this) {print(x);newLine();}}//將對象x對應的字符串+換行符寫到PrintStream流中,實際調用print()-->write().public void println(Object x) {String s = String.valueOf(x);synchronized (this) {print(s);newLine();}}//將數據args按照默認的Locale值和format格式進行格式化后寫到PrintStream流中.//方法執行等同于out.format(format, args)public PrintStream printf(String format, Object ... args) {return format(format, args);}//將數據args根據Locale值和format格式進行格式化后寫到PrintStream輸出流中//方法執行等同于out.printf(l, format,args)public PrintStream printf(Locale l, String format, Object ... args) {return format(l, format, args);}//根據默認的Locale值和format格式來格式化數據args寫到PrintStream輸出流中.public PrintStream format(String format, Object ... args) {try {synchronized (this) {ensureOpen();if ((formatter == null)|| (formatter.locale() != Locale.getDefault()))formatter = new Formatter((Appendable) this);formatter.format(Locale.getDefault(), format, args);}} catch (InterruptedIOException x) {Thread.currentThread().interrupt();} catch (IOException x) {trouble = true;}return this;}//將數據args根據Locale值和format格式進行格式化后寫到PrintStream輸出流中.public PrintStream format(Locale l, String format, Object ... args) {try {synchronized (this) {ensureOpen();if ((formatter == null)|| (formatter.locale() != l))formatter = new Formatter(this, l);formatter.format(l, format, args);}} catch (InterruptedIOException x) {Thread.currentThread().interrupt();} catch (IOException x) {trouble = true;}return this;}//將字符序列csq添加到PrintStream輸出流中,此方法執行等同于 out.print(csq.toString())public PrintStream append(CharSequence csq) {if (csq == null)print("null");elseprint(csq.toString());return this;}//將字符序列csq中start(包含)位置到end(不包含)之間的子字符序列添加到PrintStream輸出流中//此方法執行等同于out.print(csq.subSequence(start, end).toString())public PrintStream append(CharSequence csq, int start, int end) {CharSequence cs = (csq == null ? "null" : csq);write(cs.subSequence(start, end).toString());return this;}//將單個字符添加到PrintStream輸出流中.此方法執行等同于out.print(c)public PrintStream append(char c) {print(c);return this;} }

總結

PrintStream繼承自OutputStream,屬于字節流的一種,方法包含寫入單個字節和字節數組的方法.相似流有PrintWriter,繼承自Writer()方法,屬于字符流的一種.PrintWriter流中沒有寫入字節的方法,而有寫入單個字符和字符數組的方法.

總結

以上是生活随笔為你收集整理的Java IO流之PrintStream分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。