多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > Java之NIO(一)Channel和Buffer

Java之NIO(一)Channel和Buffer

來源:程序員人生   發(fā)布時間:2015-06-05 09:17:41 閱讀次數(shù):3881次

java NIO 就是NEW I O,他與傳統(tǒng)IO的最大的區(qū)分是 它是非阻塞IO。

Java NIO和IO之間的主要差別:


IO                NIO

面向流            面向緩沖

阻塞IO            非阻塞IO

無                 選擇器

他們各自適用于不同的環(huán)境,這里只簡單的說明其區(qū)分,具體的見博客:

http://ifeve.com/java-nio-vs-io/

NIO的核心api 是 Channel、Buffer和Selector,本品文章側(cè)重介紹前兩種。

1個簡單例子

首先舉1個簡單的例子進(jìn)行說明,這個例子使用NIO的api向1個文件中寫入數(shù)據(jù),然后把他讀出來打印,此例子的注釋很詳細(xì),可細(xì)細(xì)品味,另外有關(guān)NIO的概述可見譯文:

http://ifeve.com/channels/

/** * NIO 簡單測試?yán)樱?個文件中寫入數(shù)據(jù),然后把它讀出來。這個例子 * 主要說明 NIO 和傳統(tǒng)IO的不同,需要注意channel 和 buffer的使用。 * 理解 NIO 是面向緩沖的。而IO是面向流的。 * * 以下例子要理解NIO的使用 進(jìn)程,1 定義1個 channel , 2,定義1個buffer * 3 向buffer寫數(shù)據(jù) (寫的含義有兩種,與channel有關(guān)) 4 轉(zhuǎn)換為讀模式 5.讀取buffer數(shù)據(jù) (讀的含義與channel的方向有關(guān)) * */ public class Main { public static void main(String[] args) throws IOException { File a = new File("test.txt"); if (!a.exists()) { a.createNewFile(); } FileOutputStream out = new FileOutputStream(a); //構(gòu)造輸出channel,這里使用filechannel FileChannel outChannel = out.getChannel(); String testStr = "Lina , i love you"; //構(gòu)造1個輸出的緩存。 ByteBuffer byteBuffer1 = ByteBuffer.allocate(512); //put方法向緩存中寫數(shù)據(jù),注意是寫 byteBuffer1.put(testStr.getBytes()); //下面的3行代碼將向文件中寫數(shù)據(jù),filp()方法把buffer轉(zhuǎn)換為讀模式,然后使用channel的寫方法寫數(shù)據(jù)到文件。 //注意的是,outChannel 寫入文件的數(shù)據(jù)是從charbuffer“讀取”的, 寫入或讀取 是針對buffer而言,不是根據(jù)channel說的,這點需要理解 byteBuffer1.flip(); while (byteBuffer1.hasRemaining()) { outChannel.write(byteBuffer1); } outChannel.close(); out.close(); FileInputStream in = new FileInputStream(a); //構(gòu)造輸入channel和 buffer,跟以上對照,channel的方向是 底層的包裝層決定的。 FileChannel inChannel = in.getChannel(); ByteBuffer inBuffer = ByteBuffer.allocate(512); //循環(huán)讀取文件數(shù)據(jù),寫入到 buffer中,注意這里還是寫入buffer while (inChannel.read(inBuffer)!=⑴) { } //轉(zhuǎn)換為讀模式,flip方法調(diào)用后,buffer會產(chǎn)生1些變化,這里暫不討論。 inBuffer.flip(); byte[] dest = new byte[inBuffer.limit()]; //讀取數(shù)據(jù)到byte數(shù)組。 inBuffer.get(dest, 0, inBuffer.limit()); inChannel.close(); in.close(); System.out.println(new String(dest)); }


Channel

官方文檔定義channel指“與1個實體的連接”,這個實體可以是1個裝備、文件、socket等。channel的接口定義本身簡單,JDK提供了幾種實現(xiàn)。

public interface Channel extends Closeable { public boolean isOpen(); public void close() throws IOException; }


上圖展現(xiàn)了channel的體系,可見WritableByteChannel和ReadableByteChannel 分別擴(kuò)大了channel接口,加入了讀和寫的功能,其中最多見的實現(xiàn)已分別用紅色框起來,他們分別適用于不同的場合。

FileChannel 從文件中讀寫數(shù)據(jù),與fileinput/outputStream對應(yīng)

DatagramChannel 能通過UDP讀寫網(wǎng)絡(luò)中的數(shù)據(jù)。對應(yīng)DatagramSocket

SocketChannel 能通過TCP讀寫網(wǎng)絡(luò)中的數(shù)據(jù)。對應(yīng)IO中的socket

ServerSocketChannel可以監(jiān)聽新進(jìn)來的TCP連接,像Web服務(wù)器那樣。對每個新進(jìn)來的連接都會創(chuàng)建1個SocketChannel。對應(yīng)IO中ServerSocket

Buffer

首先貼1張圖來表示Channel和Buffer的關(guān)系,即channel是通過buffer來讀寫數(shù)據(jù)的。關(guān)于buffer,http://ifeve.com/buffers/ ,以上地址翻譯的很好,這里摘出里面的部份內(nèi)容。


基本用法

簡單的例子中,已說明了channel和buffer的基本用法這里,做個簡單的總結(jié),

使用Buffer讀寫數(shù)據(jù)1般遵守以下4個步驟:

1.     寫入數(shù)據(jù)到Buffer

2.     調(diào)用flip()方法

3.     從Buffer中讀取數(shù)據(jù)

4.     調(diào)用clear()方法或compact()方法

當(dāng)向buffer寫入數(shù)據(jù)時,buffer會記錄下寫了多少數(shù)據(jù)。1旦要讀取數(shù)據(jù),需要通過flip()方法將Buffer從寫模式切換到讀模式。在讀模式下,可以讀取之前寫入到buffer的所有數(shù)據(jù)。

1旦讀完了所有的數(shù)據(jù),就需要清空緩沖區(qū),讓它可以再次被寫入。有兩種方式能清空緩沖區(qū):調(diào)用clear()或compact()方法。clear()方法會清空全部緩沖區(qū)。compact()方法只會清除已讀過的數(shù)據(jù)。任何未讀的數(shù)據(jù)都被移到緩沖區(qū)的起始處,新寫入的數(shù)據(jù)將放到緩沖區(qū)未讀數(shù)據(jù)的后面。

Buffer的屬性

buffer有3個基本的屬性capacity limit position.

capacity 是指buffer的大小,在buffer建立的時候已肯定。

limit 當(dāng)buffer處于寫模式,指還可以寫入多少數(shù)據(jù),處于讀模式,指還有多少數(shù)據(jù)可以讀。

position 當(dāng)buffer處于寫模式,指下1個寫數(shù)據(jù)的位置, 處于讀模式,當(dāng)前將要讀取的數(shù)據(jù)的位置。每讀寫1個數(shù)據(jù),position+1

也就是 limit 和position在 buffer的讀/寫時的含義不1樣。當(dāng)調(diào)用buffer的flip方法,由寫模式變成讀模式時,

limit(讀)=position(寫)

position(讀) =0;

Buffer的類型

buffer有多種類型,不同的buffer提供不同的方式操作buffer中的數(shù)據(jù)。


buffer的操作

寫數(shù)據(jù)

寫數(shù)據(jù)到buffer有兩種情況:

1.     從channel寫到 buffer,如例子中channel從文件中讀取數(shù)據(jù),寫到channel

2.     直接調(diào)用put方法,往里面寫數(shù)據(jù)

flip()

這個操作已解釋過,轉(zhuǎn)換buffer為讀模式

讀數(shù)據(jù)

從Buffer中讀取數(shù)據(jù)有兩種方式:

1.     從Buffer讀取數(shù)據(jù)到Channel。

2.     使用get()方法從Buffer中讀取數(shù)據(jù)。

rewind()

Buffer.rewind()將position設(shè)回0,所以你可以重讀Buffer中的所有數(shù)據(jù)。limit保持不變,依然表示能從Buffer中讀取多少個元素(byte、char等)。

clear() 和 compact()方法

1旦讀完Buffer中的數(shù)據(jù),需要讓Buffer準(zhǔn)備好再次被寫入。可以通過clear()或compact()方法來完成。

如果調(diào)用的是clear()方法,position將被設(shè)回0,limit被設(shè)置成 capacity的值。換句話說,Buffer 被清空了。Buffer中的數(shù)據(jù)并未清除,只是這些標(biāo)記告知我們可以從哪里開始往Buffer里寫數(shù)據(jù)。

如果Buffer中有1些未讀的數(shù)據(jù),調(diào)用clear()方法,數(shù)據(jù)將“被遺忘”,意味著不再有任何標(biāo)記會告知你哪些數(shù)據(jù)被讀過,哪些還沒有。

如果Buffer中仍有未讀的數(shù)據(jù),且后續(xù)還需要這些數(shù)據(jù),但是此時想要先先寫些數(shù)據(jù),那末使用compact()方法。

compact()方法將所有未讀的數(shù)據(jù)拷貝到Buffer起始處。然后將position設(shè)到最后1個未讀元素正后面。limit屬性仍然像clear()方法1樣,設(shè)置成capacity。現(xiàn)在Buffer準(zhǔn)備好寫數(shù)據(jù)了,但是不會覆蓋未讀的數(shù)據(jù)。
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: www.久| 午夜理伦三级播放 | 中文字幕在线视频播放 | 黄色录像大片毛片aa | 日韩免费网站 | 女性一级全黄生活片在线播放 | 久久久久久久久久久9精品视频 | 亚洲欧美综合网 | 国产国语一级a毛片高清视频 | 日本综合欧美一区二区三区 | 久久精品一区二区三区不卡牛牛 | 色日韩 | 免费观看在线永久免费xx视频 | 亚洲欧美一区二区三区九九九 | 日本一级黄色 | 免费一级欧美毛片 | 小说区图片区亚洲 | 现代激情校园春色 | 一区二区三区成人 | 在线观看免费xx高清视频 | www.久久精品 | 国产亚洲一区在线 | 欧美日韩在线一区二区三区 | 成人免费看黄页网址大全 | 亚洲视频在线观看免费视频 | 午夜三级在线 | 波多野结衣中文一区二区免费 | 欧美色综合高清免费 | 亚洲精国产一区二区三区 | 欧美jizz大又粗 | 欧美成人a视频 | 亚洲福利精品一区二区三区 | 欧美日韩xxx | 欧美成人在线影院 | 福利久久| 亚洲图片天堂 | 欧美日韩中文字幕一区二区高清 | 欧美一区二区三区影院 | 福利精品一区 | 精品视频一区二区三区四区五区 | 亚洲毛片在线 |