Java中IO處理類介紹

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的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章