摘要:字節流和字符流和和兩個抽象類是所有輸入流的基類本身并不能創建實例來執行輸入但它們將成為所有輸入流的模板他們的方法是所有輸入流都可用的方法中包含如下三個方法從輸入流中讀取單個字節返回所讀取的字節數據字節數據可直接轉換為類型從輸入流中讀取最多個
字節流和字符流 InputStream和Reader
InputStream和Reader兩個抽象類是所有輸入流的基類,本身并不能創建實例來執行輸入,但它們將成為所有輸入流的模板.他們的方法是所有輸入流都可用的方法.
InputStream中包含如下三個方法int read() 從輸入流中讀取單個字節,返回所讀取的字節數據(字節數據可直接轉 換為int類型).
int read(byte[] b) 從輸入流中讀取最多b.lenght個字節數據,并將其存貯在數組b中,返回實際讀取的字節數.
int read(byte[] b,int off,int len) 從輸入流中讀取最多的len個字符的數據,并存在數組b中,放入數組b中時,從off的位置開始,返回實際讀取的字節數.
Reader中包含如下三個方法int read() 從輸入流中讀取單個字符,返回所讀取的字符數據(字符數可以直接轉換為int類型)
int read(char[] cbuf) 從輸入流中讀取最多的cbuf.length個字符數據,并將其存儲在字符數組cbuf中,返回實際讀取的字符數.
int read(char cbuf,int off,int len) 從輸入流中讀取最多len個字符的數據,并將其存在cbuf中,從off位置開始,返回實際的讀取的字符數.
使用FileInputStream讀取自身
javapublic void readFile() throws IOException { //創建字節輸入流 FileInputStream fis = new FileInputStram("FileInputTest.java"); //創建一個長度為1024的緩沖數組 byte[] bbuf = new byte[1024]; //保存實際讀取的字節數 int hasRead = 0; //循環讀取文件內容 while ((hasRead = fis.read(bbuf)) > 0) { System.out.println(new String(bbuf,0,hasRead)); } //文件IO資源不屬于內存資源 //垃圾回收無法回收該資源 //必須顯式關閉 fis.close(); }
使用FileReader讀取文件自身
public void readFile() throws IOException { FileReader fr = new FileReader("FileReaderTest.java"); char[] cbuf = new char[32]; int hasRead = 0; while ((hasRead = fr.read(cbuf)) > 0) { System.out.println(new String(cbuf,0,hasRead)); } fr.clse(); }
此外,InputStream和Reader還支持如下幾個方法來支持指針的移動
void mark(int readAheadLimit) 在記錄指針當前位置記錄一個標記(mark).
boolean markSupported() 判斷此輸入流是否支持mark()操作
void reset() 將此流的記錄指針重新定位到上一次記錄標記的位置(mark).
long skip(long n) 記錄指針向前移動n個字節/字符.
void write(int c) 將指定的字節/字符輸出到輸出流中,其中c既可以代表字節,也可以代表字符.
void write(byte[]/char[] buf) 將字節數組/字符數組中的數據輸出到指定輸出流中.
void write(byte[]/char[] buf,int off,int len) 將字節數組/字符數組從off位置開始,長度為len的字節/字符輸出到輸出流中.
Writer里還包含如下兩個方法:
* void write(String str) 將str字符串輸出到指定輸出流中
* void write(String str,int off,int len) 將str字符串里從off位置開始,長度為len輸出到指定輸出流中.
下面的程序使用FileInputStream來執行輸入,通過FileOutputStream執行輸出,實現復制文件的功能
javapublic void copyFile() throws IOException { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("outfile.txt"); fos = new FileOutputStream("newfile.txt"); byte[] bbuf = new byte[32]; int hasRead = 0; while ((hasRead =fis.read(bbuf)) > 0) { fos.write(bbuf,0,hasRead); } } catch(IOException ioe) { ioe.printStatckTrance(); } finally { if (fis != null) { fis.close(); } if(fos != null) { fos.close(); } } }
如果希望直接輸出字符串內容,使用Writer更為方便.
javapublic void out() { FileWriter fw = null; try { fw = new FileWrite("file.txt"); fw.write("但我不能放歌, "); fw.write("悄悄是別離的笙簫; "); fw.write("夏蟲也為我沉默, "); fw.write("沉默是今晚的康橋! "); } catch (IOException ioe) { } finally { if(null != fw) { fw.close(); } } }
上面程序會在當前目錄下輸出file.txt,文件內容就是程序中輸出內容.
輸入/輸出流體系分類 | 字節輸入流 | 字節輸出流 | 字符輸入流 | 字符輸出流 |
---|---|---|---|---|
抽象基類 | InputStream | OutputStream | Reader | Writer |
訪問文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
訪問數組 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
訪問管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
訪問字符串 | StringReader | StringWriter | ||
緩沖流 | BufferedInputStream | BufferedOutputStream | BufferedRead | BufferedWriter |
轉換流 | InputStreamReader | OutputStreamReader | ||
對象流 | ObjectInputStream | ObjectOutput | ||
抽象基類 | FilterInputStream | FilterOutPutStream | FilterReader | FilterWriter |
打印流 | PrintStream | PrintWriter | ||
推回輸入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
上面表中粗體字標出類的代表節點流,必須直接與指定物理節點關聯;斜體字標出的為抽象基類,無法創建實例.
字節流比字符流功能強大,因為計算機中所有數據都是二進制的.字節流可以處理所有的二進制文件.如果使用字節流來處理文本文件時,需要使用合適的方式把字節轉換成字符,無形中增加了編程的復雜程度.所以通常有個規則,如果需要進行輸入/輸出的是文本內容,應考慮使用字符流,如果需要進行輸入/輸出的二進制內容,應考慮使用字節流.
使用字符串作為物理節點:
javapublic void StringNodeTest() { String src = "軟泥上的青荇, " +"油油的在水底招搖; " +"在康河的柔波里, " +"我甘心做一條水草。"; StringReader sr = new StringReader(src); char[] cbuf = new char[32]; int hasRead = 0; try { while((hasRead =sr.read(cbuf)) > 0) { System.out.println(new String(cbuf,0,hasRead)); } } catch (IOException ioe) { ioe. } finally { if (null != sr){ sr.close(); } } }轉換流
IO體系中提供了2個轉換流,用于實現將字節流轉換成字符流.InputStreamReader將字節輸入流轉換成字符輸入流,OutputStreamWriter將字節輸出流轉換成字符輸出流.
Java并沒有提供字符流轉換成字節流接口,看似設計遺漏.考慮下字符流和字節流的差別,字節流比字符流使用范圍更廣,但字符流操作比字節流方便,如果已經有一個字符流,為什么還要換成字節流,既然知道字節流的內容是文本,那么轉換成字符流更方便一些,所以Java沒有提供字符流到字節流的轉換.
下面的例子通過使用鍵盤輸入(System.in).這個標準的輸入流是InputStream實例,使用起來不太方便,鍵盤輸入的都是純文本,使用InputStreamReader將其轉換為字符輸入流,普通Reader讀起來依舊不方便,于是再轉換成BufferedReader,利用它的readLine()方法可以一次讀一行.
javapublic void convInput() { BufferedReader br = null; try { //System.in轉換成Reader對象 InputStreamReader reader = new InputStreamReader(System.in); //將Reader包裝成BufferedReader br = new BufferedReader(reader); String buffer = null; While((buffer = br.readLine()) != null) { if("exit".equals(buffer)) { System.exit(1); } System.out.println("輸入內容為:" + buffer); } } catach (IOException ioe) { } finally { try { if (null != br) { br.close(); } } catach (IOException ioe) { } } }推回輸入流
在IO體系中,有2個特殊的流.PushbackInputStream和PushbackReader.提供如下三個方法:
* void unread(byte[]/char[] buf) 將一個字節數組內容推回到推回緩沖區里,從而允許重復讀取剛剛的內容.
* void unread(byte[]/char[] b,int off,int len) 將一個字節/字符數組從off開始,長度為len字節/ 字符的內容推回到推回緩沖區里,從而允許重復讀取剛剛的內容.
* void unread(int b) 將一個字節/字符推回到推回緩沖區,從而允許重復讀取剛剛讀取的內容.
這三個方法和InputStream和Reader里三個read方法一一對應,這兩個推回輸入流都帶有一個推回緩沖區,當程序調用這兩個推回輸入流的unread方法時,系統會把指定數組的內容推回到該緩沖區里,從而允許重復讀取剛剛讀取的內容.
java/**省略無數代碼**/ PushbackReader pr = null; try { pr = new PushbackReader(new FileReader("E:workplace1 eviewsrcioPushbackReaderTest.java"), 64); char[] buf = new char[32]; //保存上次讀取的字符串內容 String lastContent = ""; int hasRead = 0; while ((hasRead = pr.read(buf)) > 0) { //讀取到內容轉換成字符串 String content = new String(buf,0,hasRead); int targetIndex = 0; //將上一次內容和本次內容拼起來 檢查是否包含目標字符串 //如果包含目標字符串 if ((targetIndex = (lastContent + content).indexOf("new PushbackReader")) > 0) { //將本次內容上次內容一起退回到推回緩沖區 pr.unread((lastContent + content).toCharArray()); //再次讀取指定程度的內容(目標字符串之前的內容) pr.read(buf,0,targetIndex); //打印讀取內容 System.out.println(new String(buf,0,targetIndex)); System.exit(0); } else { System.out.println(lastContent); lastContent = content; } } /**省略無數代碼**/重定向標準輸入/輸出
Java的標準輸入輸出分別通過System.in和System.out來代表,默認情況下他們分別代表鍵盤和顯示器.
System類中提供三個重定向輸入/輸出標準的方法:
* static void setErr(PrintStream err) 重定向"標準"錯誤輸出流
* static void setIn(InputStream in) 重定向"標準"輸入流
* static void setOut(PrintStream out) 重定向"標準"輸出流
下面的程序通過重定向標準輸出流,將System.out的輸出重定向到到文件輸出:
java/**省略無數代碼**/ PrintStream ps = null; try { //創建重定向需要的輸出流 ps = new PrintStream(new FileOutputStream("out.txt")); //將標準輸出流重定向到ps輸出流 System.setOut(ps); //測試輸出 System.out.println("普通字符串"); System.out.println(new RedirectOut()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (null != ps) { ps.close(); } } /**省略無數代碼**/
下面的程序通過重定向標準輸入流,將System.in重定向到指定文件而不是鍵盤:
java/**省略無數代碼**/ FileInputStream fis = null; try { fis = new FileInputStream("E:workplace1 eviewsrcioRedirectIn.java"); //將標準輸入重定向到fis輸入流 System.setIn(fis); //獲取標準輸入 Scanner sc = new Scanner(System.in); //設置只把回車作為分隔符 sc.useDelimiter(" "); while (sc.hasNext()) { System.out.println("鍵盤輸入內容為:" + sc.next()); } /**省略無數代碼**/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/64415.html
摘要:流分類由此可見,流很龐大從不同角度進行分類數據分類按處理數據單位分為字節流和字符流。處理數據是音頻視頻文本等一切為字節流,僅能處理文本的為字符流。功能分類節點流和處理流。從向一個特定的設備磁盤網絡等讀寫數據的流稱為節點流,也常被稱為低級流。 嗨嘍,小樂又來了,今天要給大家送上的技術文章是Java重點知識-IO流。 先來看看IO流的思維導圖吧。showImg(https://segmen...
摘要:除非文件用自帶的記事本打開我們能夠讀懂,才采用字符流,否則建議使用字節流。 第四階段 IO IO流 前言: 前面的學習我們只能夠在已有的一定封閉范圍內進行一些操作,但是這顯然是無趣的,也是不支持我們實現一些復雜的需求,所以Java提供IO流這樣一種概念,方便我們對數據進行操作 而使用IO流我們可以實現一些強大的功能,例如針對文件的移動復制等操作,又或者程序與外部文件之間的數據存儲或者讀...
摘要:從通道進行數據寫入創建一個緩沖區,填充數據,并要求通道寫入數據。三之通道主要內容通道介紹通常來說中的所有都是從通道開始的。從中選擇選擇器維護注冊過的通道的集合,并且這種注冊關系都被封裝在當中停止選擇的方法方法和方法。 由于內容比較多,我下面放的一部分是我更新在我的微信公眾號上的鏈接,微信排版比較好看,更加利于閱讀。每一篇文章下面我都把文章的主要內容給列出來了,便于大家學習與回顧。 Ja...
摘要:把字節序列恢復為對象的過程稱為對象的反序列化。代表對象輸入流,它的方法從一個源輸入流中讀取字節序列,再把它們反序列化為一個對象,并將其返回。接口繼承自接口,實現接口的類完全由自身來控制序列化的行為,而僅實現接口的類可以采用默認的序列化方式。 把對象轉換為字節序列的過程稱為對象的序列化。把字節序列恢復為對象的過程稱為對象的反序列化。 對象的序列化主要有兩種用途: 1) 把...
閱讀 2756·2023-04-25 14:15
閱讀 2704·2021-11-04 16:11
閱讀 3395·2021-10-14 09:42
閱讀 442·2019-08-30 15:52
閱讀 2826·2019-08-30 14:03
閱讀 3545·2019-08-30 13:00
閱讀 2112·2019-08-26 11:40
閱讀 3307·2019-08-26 10:25