1. 程式人生 > >Java中的IO(面試有時會問java io的問題)

Java中的IO(面試有時會問java io的問題)

深入分析Java I/O 工作機制

作者:egg

IOJava及眾多程式語言很重要的一塊,同時很多程式的瓶頸和耗時操作也都在IO這塊。所以能夠很好的解決IO問題對提高程式效能有很大的幫助!本章我們將要系統的對Java IO做個分析,通過理論加實踐,希望讀者朋友們能真正徹底的理解並且掌握了它。本章系Java之美[從菜鳥到高手演變]系列Java IO,通過本章的學習,讀者朋友們能基本瞭解到關於IO的很多知識。日後加以理解、分析、在專案中實踐,定能靈活運用!

一、簡介

IO操作面臨很多問題,資訊量的巨大,網路的環境等等,因為IO不僅僅是對本地檔案、目錄的操作,有時對二進位制流、還有一部分是網路方面的資源,所以多種原因直接造成

IO操作無疑是耗時且複雜多變的。JavaIO的支援是個不斷的演變過程,經過了很多的優化,直到JDK1.4以後,才趨於穩定,在JDK1.4中,加入了nio類,解決了很多效能問題,雖然我們有足夠的理由不去了解關於Java IO以前的情況,但是為了學好現在的類,我們還是打算去研究下,通過掌握類的優化情況來徹底理解IO的機制!Java IO主要主要在java.io包下,分為四大塊近80個類:

1、基於位元組操作的I/O介面:InputStreamOutputStream

2、基於字元操作的I/O介面:WriterReader

3、基於磁碟操作的I/O介面:File

4、基於網路操作的

I/O介面:Socket(不在java.io包下)

影響IO效能的無非就是兩大因素:資料的格式及儲存的方式,前兩類主要是資料格式方面的,後兩個類是儲存方式方面的:本地和網路。所以策劃好這兩個方面的活動,有助於我們合理使用IO

二、基於位元組的I/O操作(InputStreamOutputStream)

我們先來看看類圖:

圖1

圖2

二者類似,我只詳細講解InputStream類,OutputStream留給大家自己去學習。InputStream類是個抽象類,裡面核心的方法就是read()、read(byte b[])、read(byte b[], int off, int len),這三個方法是用於讀取資料的底層的方法,他們可以用來讀取一下這些型別的資料:

A. 位元組陣列

B. String物件

C. 檔案

D. 管道,從一端進入,從另一端輸出

E. 流

F. internet資源

每一種資料來源都有相應的InputStream子類,因為InputStream是個處於頂層的類,用來處理各種資料來源的類都繼承了InputStream類,我們來看看這些類:

ByteArrayInputStream:處理位元組陣列的類,允許將記憶體的緩衝區當做InputStream使用。

StringBufferInputStream:將String轉換成InputStream,內部實現用的是StringBuffer

FileInputStream:從檔案中讀取資料。

PipedInputStream:用於從管道中讀取資料。

SequenceInputStream:將多個流物件轉化成一個InputStream

FilterInputStream:裝飾器類,為其它InputStream類提供功能。

做過關於IO操作的讀者知道,我們很少單獨使用哪個類來實現IO操作,平時都是幾個類合起來使用,這其實體現了一種裝飾器模式(詳見:http://blog.csdn.net/zhangerqing)的思想,在後面的分析中我們會詳細的分析。從上面的圖1中我們可以看出,FilterInputStream雖說是Inputstream的子類,但它依然是BufferedInputStreamDataInputStreamLineNumberInputStreamPushbackInputStream類的父類,這四個類分別提供了最貼近我們程式設計師使用的方法,如:readInt() 、readInt()、readInt()等等。對於IO操作,不管是磁碟還是網路,最終都是對位元組的操作,而我們平時寫的程式都是字元形式的,所以在傳輸的過程中需要進行轉換。在字元到位元組的轉換過程中,我們需要用到一個類:InputStreamReader

三、基於字元的I/O操作(WriterReader)

圖3

圖4

WriterReader操作的目的就是操作字元和不是位元組,和InputStreamOutputStream配合增加IO效果。通過InputStreamReaderOutputStreamReader可以進行位元組和字元的轉換,設計WriterReader的目的是國際化,使IO操作支援16位的Unicode我把它們單獨的畫出來,因為要是全畫的話,太大了放不下,有興趣的TX可以在rational rose中匯入其帶的JDK類圖看看,很過癮的!

四、基於磁碟的I/O操作(File)

五、基於網路的I/O操作(Socket)

六、NIO

四-六部分由於時間關係,還沒有整理完,後續會補出來!

七、經典IO操作

1、緩衝輸入檔案。

  1. import java.io.BufferedReader;  
  2. import java.io.FileReader;  
  3. publicclass InputStreamTest {  
  4.     publicstatic String read(String filename) throws Exception {  
  5.         BufferedReader br = new BufferedReader(new FileReader(filename));  
  6.         String s;  
  7.         StringBuffer sb = new StringBuffer();  
  8.         while ((s = br.readLine()) != null) {  
  9.             sb.append(s + "\n");  
  10.         }  
  11.         br.close();  
  12.         return sb.toString();  
  13.     }  
  14.     publicstaticvoid main(String[] args) throws Exception {  
  15.         System.out.println(read("src/InputStreamTest.java"));  
  16.     }  
  17.  }  

這段程式碼是從磁碟讀入InputStreamTest.java檔案,然後轉換成字串。輸出就是將原始檔原樣輸出。

2、從記憶體中讀取。

  1. import java.io.StringReader;  
  2. publicclass MemoryInput {  
  3.     publicstaticvoid main(String[] args) throws Exception {  
  4.         StringReader in = new StringReader(  
  5.                 InputStreamTest.read("src/MemoryInput.java"));  
  6.         int c;  
  7.         while ((c = in.read()) != -1)  
  8.             System.out.println((char) c);  
  9.     }  
  10. }  

read返回的是int型別的資料,所以在輸出語句中用char做了強型別轉換。該程式將一個一個的輸出字元。

3、基本的檔案輸出。

  1. import java.io.BufferedReader;  
  2. import java.io.BufferedWriter;  
  3. import java.io.FileWriter;  
  4. import java.io.PrintWriter;  
  5. import java.io.StringReader;  
  6. publicclass BasicFileOutput {  
  7.     static String file = "basie.out";  
  8.     publicstaticvoid main(String[] args) throws Exception {  
  9.         BufferedReader in = new BufferedReader(new StringReader(  
  10.                 InputStreamTest.read("src/BasicFileOutput.java")));  
  11.         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(  
  12.                 file)));  
  13.         int lineCount = 1;  
  14.         String s;  
  15.         while ((s = in.readLine()) != null) {  
  16.             out.println(lineCount++ + ": " + s);  
  17.         }  
  18.         out.close();  
  19.         System.out.println(InputStreamTest.read(file));  
  20.     }  
  21. }  

輸出:

1: import java.io.BufferedReader;

2: import java.io.BufferedWriter;

3: import java.io.FileWriter;

 4RandomAccessFile

RandomAccessFile被我們稱為”自我獨立的類”,因為它獨立於我們前面說的IO類,與InputStreamOutputStream沒什麼關係,除了實現了DataOutput, DataInput兩個介面外。所有方法都是重新編寫,而且很多都是native方法,我們來看個例子,瞭解下這個類:

5、管道流

八、標準I/O

就是我們最原始的使用的從控制檯輸入或者輸出的那些類和方法,如System.inSystem.out等。

  1. publicclass StandardIO {  
  2.     publicstaticvoid main(String[] args) throws IOException {  
  3.         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));  
  4.         String s;  
  5.         while ((s = in.readLine()) != null && s.length() != 0)  
  6.             System.out.println(s);  
  7.     }  
  8. }  

System.in返回的是未經包裝的InputStream物件,所以需要進行裝飾,經InputStreamReader轉換為Reader物件,放入BufferedReader的構造方法中。除此之外,System.outSystem.err都是直接的PriintStream物件,可直接使用。我們也可以使用java.util包下的Scanner類來代替上述程式:

  1. publicclass StandardIO {  
  2.     publicstaticvoid main(String[] args) throws IOException {  
  3.         Scanner in = new Scanner(System.in);  
  4.         String s;  
  5. 相關推薦

    JavaIO面試時會java io的問題

    深入分析Java I/O 工作機制 作者:egg IO是Java及眾多程式語言很重要的一塊,同時很多程式的瓶頸和耗時操作也都在IO這塊。所以能夠很好的解決IO問題對提高程式效能有很大的幫助!本章我們將要系統的對Java IO做個分析,通

    java的變數原來這些詳解

    1 初識java a 開啟MyEclipse b 開啟File->new->java project (建立專案) c 在project name 起名 (給專案命名) d 開啟File->new->class name起個名字 最好叫Test (建立類並命名) e

    求兩個序數組的位數4. Median of Two Sorted Arrays

    排序 font float 序列 大小 width 技術 display 個數 先吐槽一下,我好氣啊,想了很久硬是沒有做出來,題目要求的時間復雜度為O(log(m+n)),我猜到了要用二分法,但是沒有想到點子上去。然後上網搜了一下答案,感覺好有罪惡感。 題目原型 正確的

    jsp的盲區-面試可能會到的東西

    結果 body style 成員 light 有趣 一行 int 為什麽 1、今天看到一個有趣的JSP題目。 <body> This is my JSP page. <br> <% int a = 10; %&g

    JavalongLong與intInteger之間的轉換

    轉化 string long tar str 基礎數據類型 ava detail 參考 一、將long型轉化為int型,這裏的long型是基礎類型: long a = 10; int b = (int)a; 二、將Long型轉換為int型,這裏

    java的訪問控制什麽用?如何用法?請舉例

    nbsp con eth 不能 ret direct col The www. 9.訪問控制 (視頻下載) (全部書籍) 【新手可忽略不影響繼續學習】 訪問控制有什麽用?在軟件公司裏是這麽用的,我們想像一種場景,在你的類中,你編了三個私有方法,馬克-to-win,別人當然都

    java接口interface什麽用呢?舉例!

    進步 gin details http 服務 mark html 沒有 國家 通過運用關鍵字interface,Java允許你定義一個接口。接口只有方法的定義,沒有方法的任何實現。那這有什麽意義呢?馬克-to-win: 接口就像一個服務合同。接口只關心必須得幹什麽而不關心如

    java異常Exception的定義,意義和用法。舉例

    use 詳情 put 視頻下載 ati itl url index ring 1.異常(Exception)的定義,意義和用法 (視頻下載) (全部書籍) 我們先給出一個例子,看看異常有什麽用? 例:1.1-本章源碼 public class Test { publi

    javaexception和error什麽區別,運行時異常和一般異常什麽區別

    顯示 error cat 捕獲 導致 避免 dex 源代碼 tof 1.exception和error都是繼承了throwable類,在java中只有throwable類型的實例才可以被拋出(throw)或者捕獲(catch),它是異常處理機制的基本組成類型 2.excep

    Java基礎知識JAVAString、StringBuffer、StringBuilder類的區別

    pen 順序 ava tps 進行 exp ringbuf https 對他 java中String、StringBuffer、StringBuilder是編程中經常使用的字符串類,他們之間的區別也是經常在面試中會問到的問題。現在總結一下,看看他們的不同與相同。

    java介面interface及使用方法和注意事項

    1、介面:一種把類抽象的更徹底,接口裡只能包含抽象方法的“特殊類”。介面不關心類的內部狀態資料,定義的是一批類所遵守的規範。(它只規定這批類裡必須提供某些方法,提供這些方法就可以滿足實際要求)。 在JAVA程式語言中是一個抽象型別,是抽象方法的集合,介面通常以interface來宣告。一個類通過

    JAVAgetClass以及getName()方法

    getClass public final Class<?> getClass() 返回此 Object 的執行時類。返回的 Class 物件是由所表示類的 static synchronized 方法鎖定的物件。

    java克隆淺拷貝的簡單使用程式碼

    java中克隆的使用 1) 在被克隆類中,要提供實現克隆的介面: class Cat implements Cloneable{ } 2) 在被克隆的類中重寫clone方法,使其public化 class Cat implements Cloneable{

    JAVAOOAD面向物件分析與設計依賴倒置原則程式碼例項

    簡介:什麼是依賴倒置原則? 軟體設計中,多層次之間相互依賴關係需要倒置為抽象類或介面,而不是直接依賴於具體的實現。 具體表現為: 1、上層模組不應該直接依賴下層實現,而應該依賴下層的抽象 2、每一個單獨的層次,抽象不應該依賴於細節,而細節應該依賴於抽象。 現在有一個使用者類UserBea

    Java的clone()方法什麼作用

    Java在處理基本資料型別(例如int、char、double等)時,都是採用值傳遞(傳遞的是輸入引數的副本)的方式執行,除此之外的其它型別(物件啊,String型別等)都是按引用傳遞(傳遞的是物件的一個引用)的方式執行。物件除了在函式呼叫時是引用傳遞,在使用“=”也是採用引用傳遞 cl

    javaheap和stack什麼區別

    java的記憶體分為兩類,一類是棧記憶體,一類是堆記憶體。棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。     &nbs

    JavaTimeZone時區類的簡單使用

    package com.wk.time import java.util.TimeZone; public class LocaleTimeZone { public static void main(String[] args) { TimeZone zone =

    javapackage的使用理解

    java中package(包)的使用理解 2017年02月05日 02:30:08 FengGLA 閱讀數:17755 標籤: java 更多 個人分類: java學習筆記 版權宣告:本文為博主原創文章,未經博主允許不得轉載。

    java實用類

    一、String類 1.在java中String類比較特殊,它是一種引用資料型別,位於java.lang包中。 2.String類的常用方法 (1)length()方法,是求字串的長度 String str="abcdefg"; int s=str.length(); //注意,

    java集合

    一、Map介面 1.Map介面是儲存一組成對出現的鍵(key)---- 值(value)物件。 2.Map介面中的key集無序,唯一,可以為空null,也就是隻有一個鍵集為空,如果有重複的後面的會覆蓋前面的。value集無序,允許重複。 3.Map介面得到常用方法