Java 转换流 简介
在以前的博文也提過了, java的Stream根據傳輸的最小單位, 可以分為字符流和字節流.?
字節流應用面更廣,? 而字符流在某些情況(例如文本處理)會更加方便.
而在編程中,? 有時程序接收到的是一條字節流(前提是確定該流存儲的是字符數據), 而程序員又想將其當字符流來處理. 就可以利用java中的InputStreamReader 和 OutputStreamWriter.
一, 什么是轉換流及作用
上面提到的兩個流:?? InputStreamReader 和 OutputStreamWriter 在Java中就被稱為轉換流.
以前我們提到?? InputStream 和 OutputStream代表的是字節流,? 而 Reader 和 Writer代表字符流
那么它們寫在一起是什么流?
實際它們是處理流的一種,? 必須包裹在1個字節流之上, 然后能當左字符流來處理.? 相當于把1個字節流轉換為1個字節流. 而無需關心編碼方式(Java用的是萬國碼).
另1個問題:
有沒有反過來, 把字符流轉為字節流的轉換流呢?? 答案是:? Java沒有提供.? 如有必要, 字節可以寫1個哦.
二, 1個例子
至于上面轉換流的常用方法就不一樣介紹了, 無非常用的就是 read() 和 write(), 跟字符流的對應方法基本一樣的.
現在寫1個例子:
接受用戶鍵盤輸入的1行字符(直至回車).? 放入1個字符串中.
這個需求簡單地將就是接受 由外部設備(鍵盤) 發送的數據, 接收到程序的1個String變量上.
2.1. 首先就要構造1個從鍵盤到程序的字節流
我們需要的字符, 為什么要構造1個字節流呢?? 因為能直接連接鍵盤的流只有字節流...
如果我們建立1個從文件(外部設備)到程序的InputStream,
則必須利用文本流
new FileInputStream(File f)
而在java中,鍵盤同樣會被當做1個外部輸入設備.
這個外部輸入設備有點特殊, 因為鍵盤會當成默認的系統輸入設備. 也叫標準輸入流.
而連接系統輸入設備字節流java已經幫我們封裝好了, 它就是
System.in
其中System是1個類,
in 是System類的1個靜態字段(非方法), 它返回的就是標準輸入流的對象.
同樣地, Java中也有1個標準輸出流, 它就是 System.out(同樣是1個靜態字段, 返回1個流向標準輸出設備的OutputStream) 這個流的輸出目標默認就是計算機屏幕執行Java程序的終端.
當然, 這個默認值是改變的, 我們可以利用System.setOut()來修改, 再下一篇博文會詳細提到.
具體可以看JDK API, java.lang.System類:
public static final InputStream in
“標準”輸入流。此流已打開并準備提供輸入數據。通常,此流對應于鍵盤輸入或者由主機環境或用戶指定的另一個輸入源。
out
public static final PrintStream out
“標準”輸出流。此流已打開并準備接受輸出數據。通常,此流對應于顯示器輸出或者由主機環境或用戶指定的另一個輸出目標。
對于簡單獨立的 Java 應用程序,編寫一行輸出數據的典型方式是:
???? System.out.println(data)
2.2 將標準輸入流System.in 轉為字符輸入流
如果你看懂我上面寫的什么的話, 就可以知道System.in 就是我們想要的從鍵盤到程序的一條輸入字節流.
但是對于1個字節流來講,我們只能從它讀取1個字節or1個字節數組.? 但是我們需要的是字符數據.
所以有必要將其轉換為字符流.
那么本文的主角, 轉換流 InputStreamReader就發揮作用了.
?
new InputStreamReader(System.in)上面代碼就獲得1條從鍵盤通向程序的字符流了.
2.3 從字符流里讀取一行.
上面的字符流提供了基本的read()方法,
可以讀取1個字符和1段字符數組.
問題是如何讀取一行呢?
首先要搞清楚什么是一行字符:?? 就是第一個換行符"\n"(回車) 之前的所有字符
2.3.1 方法1
既然知道了所謂一行字符就是換行符"\n" 之前的所有字符.
那么我們可以循環地執行? read() 方法去每次讀取1個字符, 然后把這個字符存放到1個StringBuffer中, 直至遇到"\n"
比如:
有人可能回問,? r.read()這個方法不是由鍵盤trigger的嗎? 不是應該卸載1個事件中?
實際上, 鍵盤在這里只是1個外部設備.
而執行1次? r.read();? (r就是字符流對象)時,? 程序會一直等鍵盤輸入, 知道鍵盤按下1個字符.
也就是說, 如果鍵盤無輸入時, 程序就一直在等待.
所以, 指向鍵盤字符流的read()時不需要寫在1個event里面的.
StringBuffer sbuffer = new StringBuffer(1024);int ic = 0;char c;Reader r = new InputStreamReader(System.in);System.out.println("please input some words, type Enter to exit:");ic = r.read();c=(char)ic;while(c != '\n'){sbuffer.append(c);ic = r.read();c=(char)ic;}
2.3.2 方法2
回顧一下方法一, 它嵌套兩個流, 原始流是System.in(字節流), 還有InputStreamReader(轉換流).
但是因為一次只能讀取1個字符,它需要用到循環, 還必須建立1個StringBuffer, 略顯復雜.
有沒有1個方法一次可以讀取1個整行呢?
這時我們可以再嵌套1個BufferedReader流.
BufferedReader流是,專門從字符流實現高效緩存讀取的一個處理流.
關鍵它具有readLine()函數, 可以一次讀取一整行, 并以字符串形式返回:
public String readLine()
??????????????? throws IOException
讀取一個文本行。通過下列字符之一即可認為某行已終止:換行 ('\n')、回車 ('\r') 或回車后直接跟著換行。
返回:
包含該行內容的字符串,不包含任何行終止符,如果已到達流末尾,則返回 null
拋出:
IOException - 如果發生 I/O 錯誤
例子代碼:
String s = null;Reader r = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(r);System.out.println("please input some words, type Enter to exit:");s = br.readLine();可以到雖然這個例子嵌套三層的流.? 但是因為避免了循環, 代碼反而簡潔.
2.4 例子的具體代碼:
上面只是分析, 最后把整個程序的代碼的例子發出來:
方法1:
import java.io.*;public class GetStrFromKeyBoard{public static void f(){String s = null;System.out.println("please input some words, type Enter to exit:");try{s = getStr();}catch(IOException e){e.printStackTrace();}System.out.println("words your just input is:");System.out.println(s); }public static String getStr() throws IOException{StringBuffer sbuffer = new StringBuffer(1024);int ic = 0;char c;Reader r = new InputStreamReader(System.in);ic = r.read();c=(char)ic;while(c != '\n'){sbuffer.append(c);ic = r.read();c=(char)ic;}r.close();return sbuffer.toString(); }}方法2:
import java.io.*;public class GetStrFromKeyBoard2{public static void f(){String s = null;System.out.println("please input some words, type Enter to exit:");try{s = getStr();}catch(IOException e){e.printStackTrace();}System.out.println("words your just input is:");System.out.println(s); }private static String getStr() throws IOException{String s = null;Reader r = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(r);s = br.readLine();r.close();return s; } }輸出結果: gateman@TPEOS Java_1 $ ant Buildfile: /media/store1/Studies/Java/java_start/Java_1/build.xmlmain:[javac] /media/store1/Studies/Java/java_start/Java_1/build.xml:10: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds[javac] Compiling 2 source files to /media/store1/Studies/Java/java_start/Java_1/build/classes[java] please input some words, type Enter to exit: Just a test[java] words your just input is:[java] Just a testBUILD SUCCESSFUL Total time: 4 seconds
總結
以上是生活随笔為你收集整理的Java 转换流 简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据流DataInput(Output)
- 下一篇: Java print流简介