Java IO 理論筆記

來源:互聯網
上載者:User

1、Java IO 流

io是java中實現輸入輸出的基礎,它可以很方便的完成資料的輸入輸出操作,Java把不同的輸入輸出抽象為流,通過流的方式允許Java程式使用相同的方式來訪問不同的輸入、輸出。

2、流的分類

輸入資料流、輸出資料流 

A、輸入資料流:只能從中讀取資料,而不能向裡面寫資料

B、 輸出資料流:只能向裡面寫資料,而不能讀資料

可以這樣理解,資料從記憶體到硬碟,通常認為是輸出資料流,即寫操作;相反,從硬碟到記憶體,通常認為是輸入資料流,即讀操作;這裡的輸入、輸出是從記憶體的角度劃分的

Java的輸入資料流主要有InputStream和Reader作為基類,而輸出資料流則主要由OutputStream和Writer作為基類;

 

位元組流和字元流

位元組流和字元流區別非常簡單,它們的用法幾乎一樣。區別在於位元組流和字元流所操作的資料單元不同:位元組流操作的最小單中繼資料是8位位元組,而字元流作為最小資料單元是16為位元組。

位元組流主要由InputStream、OutputStream作為基類,而字元流則主要由Reader和Writer作為基類完成。

節點流和處理流

按照流的角色分,可以分為節點流和處理流。

可以從、向一個特定的IO裝置,讀寫資料流,稱為節點流,節點流常常也被常務低級流(Low Level Stream)

處理流則用於對一個已經存在的流進行串連封裝,通過封裝後來實現資料的讀寫功能。處理流稱為進階流;

當用處理流的進行輸入、輸出時,程式並不會直接連接到實際資料來源,沒有和實際的輸入、輸出節點串連。使用處理流一個明顯的好處是:只要使用相同的處理流,程式就可以採用相同的輸入、輸出代碼來訪問不同資料來源,隨著處理流鎖封裝節點流的改變,程式實際所訪問的資料來源也相應發生改變。

處理流的功能主要體現在兩個方面:

效能提高:主要以增加緩衝方式來提高輸入、輸出的效率

操作的便捷: 處理流可能提供了系列便捷的方法來一次性輸入、輸出大批量的內容,而不是輸入、輸出一個或多個單位元據

處理流可以“嫁接”在任何已經存在的流的基礎上,這就允許Java應用程式採用相同的代碼、透明的方式來訪問不同的輸入、輸出裝置輸入資料流。

位元組輸入資料流InputStream和字元輸入資料流Reader

InputStream和Reader是所有輸入資料流的基類,他們都是2個抽象類別,本身並不能建立執行個體來執行輸入,但他們有輸入資料流的模版,所以它們的方法是所有的輸入資料流和輸出資料流可以用的方法。

在InputStream裡常用的方法:

int read(): 從輸入資料流中讀取單個自己

int read(byte[] b): 從輸入資料流中讀取最多b.length個位元組,將讀取的位元組存在數組b中,返回實際讀取的位元組數

int read(byte[] b, int off, int len): 從輸入資料流中讀取最多len個位元組資料,並將其儲存在數字b中,放入b數組中時,並不是從數組起點開始,而是從off位置開始,返回實際讀取位元組數。

在Reader裡經常使用的方法:

int read(): 從輸入資料流中讀取單個字元

int read(char[] c): 從輸入資料流讀取最多c.length個字元資料,並將其儲存在字元數組c中,返回實際讀取的字元

int read(char[] c, int off, int len): 從輸入資料流中讀取最多len個字元的資料,將讀取的資料放到字元數組c中儲存,從數組的off開始讀取;

InputStream、Reader還支援如下幾個方法移動指標:

void mark(int readAheadLimit): 在記錄指標當前位置第一個標記(mark)

boolean markSupported(): 判斷此輸入資料流是否支援mark()操作,即是否支援記錄標記

void reset():將此流的記錄的指標重新置放到上一次記錄的標記的位置

long skip(long n):記錄指標向前移動n個位元組、字元

OutputStream位元組輸出資料流和Writer字元輸出資料流

具有以下方法:

void write(int c): 指定的位元組、字元輸出到輸出資料流中

void write(byte[]/char[] buf): 將位元組數組/字元數組中的資料轉送到指定輸出資料流中

void write(byte[]/char[] buf, int off,int len):將指定數組中的資料輸出到指定輸出資料流中

字元輸出資料流還有以下方法:

void write(String s):將指定字串輸出到指定輸出資料流中

void write(String s, int off, int len):將位元組數組、字元數組中從off位置開始,長度為len的位元組、字元輸出到輸出資料流中

3、Java的輸入、輸出資料流:

分類

位元組輸入資料流

位元組輸出資料流

字元輸入資料流

字元輸出資料流

抽象基類

InputStream

OutputStream

Reader

Writer

訪問檔案

FileInputStream

FileOutputStream

FileReader

FileWriter

訪問數組

ByteArrayInputStream

ByteArrayOutputStream

CharArrayReader

CharArrayWriter

訪問管道

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

訪問字串

   

StringReader

StringWriter

緩衝流

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

轉換流

   

InputStreamReader

OutputStreamWriter

物件流程

ObjectInputStream

ObjectOutputStream

   

抽象基類

FilterInputStream

FilterOutputStream

FilterReader

FilterWriter

列印流

 

PrintStream

 

PrintWriter

推回輸入資料流

PushbackInputStream

 

PushbackReader

 

特殊流

DataInputStream

DataOutputStream

   

輸入、輸出資料流的體系:

推回輸入資料流:

有2個特殊流與眾不同,就是PushbackInputStream、PushbackReader,它們有以下常用方法:

void unread(byte[]/char[] buf):將一個位元組/字元數組推到緩衝區裡,運行重複讀取推回的內容

void unread(byte[]/char[] buf, int off, int len):將一個位元組/字元數組從off位置開始讀取,長度是len的字元/位元組數組的內容推回到緩衝區中,允許重複剛才讀取的內容

void unread(int b):將一個位元組、字元推回到緩衝區

這2個推回輸入資料流都帶一個緩衝區,當程式調用unread的時候,系統就會把指定數組的內容推回到緩衝區,而推回輸入資料流每次調用read的方法,總會先去讀取推回緩衝區中的內容,只有完全讀取的緩衝區裡面的內容後,而且還沒有裝滿read所需的數組,才會到原輸入資料流中讀取內容;

重新導向標準輸入輸出

在System中有3大標準輸入、輸出方法:

static void setErr(PrintStream e):重新導向“標準”錯誤輸出資料流

static void setIn(InputStream in):重新導向“標準”輸入資料流

static void setOut(OutputStream out):重新導向“標準”輸出資料流

JVM寫其他進程資料

Runtime對象有exec方法,他可以運行jvm命令列,該方法產生一個Process對象,Process對象代表由該Java程式啟動的子進程,Process類有以下方法,可以和子進程通訊;

InputStream getErrorStream():擷取子進程的錯誤流

InputStream getInputStream():擷取子進程的輸入資料流

OutputStream getOutputStream():擷取子進程的輸入資料流

4、RandomAccessFile

RandomAccessFile是Java輸入、輸出體系中功能最豐富的檔案內容訪問類,它提供了眾多方法來訪問檔案內容,它既可以讀檔案內容也可以像檔案輸出資料。它和普通的輸入、輸出資料流不同的是,它可以隨機訪問的方式,操作檔案資料。

RandomAccessFile可以自由定位檔案指標,所以RandomAccessFile可以不從開始的地方輸出,RandomAccessFile可以向已經存在的檔案後追加內容。

RandomAccessFile對象包含一個指標用來記錄當前讀寫的位置,當程式新建立一個RandomAccessFile對象時,該指標位於檔案頭部,既0的位置;當讀取或寫入了n個位元組後,檔案指標就指向最後的位置,除此之外,檔案指標也是可以隨意移動的,RandomAccessFile有以下方法操作指標:

long getFilePointer():返迴文件記錄指標的當前位置

void seek(long pos):將檔案記錄指標定位到pos位置

RandomAccessFile既可以讀也可以寫,所以它包含了完全類似於InputStream的read方法,和OutputStream的write方法,用法和原來的都一樣;而且RandomAccessFile還包含了readXxx、writeXxx的輸入輸出方法;

RandomAccessFile的檔案訪問模式:

r:以唯讀方式開啟指定檔案

rw:以讀取、寫入方式開啟指定檔案,如果檔案不存在就建立

rws:以讀取、寫入的方式開啟指定檔案,相對應rw模式,還要求檔案內容和中繼資料的每個更新都同步寫入到底層存放裝置

rwd:以讀取、寫入方式開啟指定檔案,對於rw,還要求檔案內容的每個更新都同步寫入到底層裝置

5、序列化

在遠程調用、分布式開發中常用到序列化,將java對象序列化的檔案中儲存,然後在解析的時候又還原序列化,其中需要用到Serializable介面;在實現了該介面的對象可以順利序列化成一個檔案儲存在硬碟上,還原序列化也是通過該介面的id來尋找該對象的。

transient可以忽略對象中某個屬性不被序列化。

6NIO

nio常用的包介紹:

java.io 包:主要提供了一些和Buffer相關的類

java.io.channels:包括Selector和Channel的相關類

java.nio.charset:包含和字元集相關的類

java.nio.channels.spi:提供Channel服務類

java.nio.charset.spi:提供文字集的服務類

Buffer介紹

Buffer是提取資料的容器,這裡有ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。

上面這些類,除了ByteBuffer之外,都採用類似的方法管理資料,只是各自管理的資料類型不同而已。這些Buffer都沒有構造器,通過使用如下方法來得到一個Buffer對象:

static XxxBuffer allocate(int capacity) 建立一個容量為capacity的XxxBuffer對象

ByteBuffer的子類MappedByteBuffer,它用於表示Chanael將硬碟檔案的的部分或全部內容映射到記憶體中後得到結果,通常MappedByteBuffer對象由Chanael的map方法返回。

在Buffer中有三個重要的概念:容量(capacity)、界限(limit)、位置(position)

容量(capacity):緩衝區的容量(capacity)表示該Buffer的最大資料容量,即最多可以儲存多少資料,緩衝區的容量不能為負數,在建立後是不能改變的。

界限(limit):第一個不應該被讀出或寫入的緩衝區位置索引。也就是說,位於limit後的資料既不能讀,也不能寫。

位置(position):用於指明下一個可以讀出的後者寫入的緩衝區位置索引。類似於IO流中的記錄指標位置。當剛剛建立一個Buffer對象時,容器position為0,如果從Channel讀取了2個資料到該Buffer中,則postion為2,指向Buffer中的第三個。

Buffer常用方法:

int capacity():返回Buffer的capacity的大小

boolean hasRemaining():判斷當前位置(position)和界限(limit)之間是否還有元素可以提供處理。

int limit:返回Buffer的界限(limit)的位置

Buffer limit(int newLimit)重新設定界限的值,並返回一個具有新的limit的緩衝區的對象

Buffer mark():設定Buffer的mark位置,它只能在0和位置position之間做mark

int position():返回當前Buffer的position

Buffer postion(int newPostion):設定Buffer的新位置,並返回一個具有新的limit的緩衝區對象。

int remaining():返回當前位置和界限之間的元素個數

Buffer reset():將position位置設定到mark的位置

Buffer rewind():將位置(position)設定為0,取消設定的mark

當使用put和get來訪問Buffer中的資料時,分為絕對和相對的2種:

相對的Relative:從Buffer中的當前位置讀取和寫入資料,然後將位置(position)的值按處理元素的個數相加。

絕對Absolute:直接根據索引來向Buffer中讀取或寫入資料,使用絕對方式來訪問Buffer理的資料,並不會影響位置position的值。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.