日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

xnio java_java基础篇---新I/O技术(NIO)

發布時間:2023/12/13 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 xnio java_java基础篇---新I/O技术(NIO) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在JDK1.4以前,I/O輸入輸出處理,我們把它稱為舊I/O處理,在JDK1.4開始,java提供了一系列改進的輸入/輸出新特性,這些功能被稱為新I/O(NEW I/O),新添了許多用于處理輸入/輸出的類,這些類都被放在java.nio包及子包下,并且對原java.io包中的很多類以NIO為基礎進行了改寫,新添了滿足新I/O的功能。

Java NIO和IO的主要區別

IO

NIO

面向流

面向緩沖

阻塞IO

非阻塞IO

選擇器

面向緩沖(Buffer)

在整個Java的心I/O中,所以操作都是以緩沖區進行的,使操作的性能大大提高。

操作

在Buffer中存在一系列的狀態變量,這狀態變量隨著寫入或讀取都可能會被概念,在緩沖區開元使用是三個值表示緩沖區的狀態。

position:表示下個緩沖區讀取或寫入的操作指針,沒向緩沖區中華寫入數據的時候 此指針就會改變,指針永遠放在寫入的最后一個元素之后。即:如果寫入了4個位置的數據,則posotion會指向第5個位置。

Limit:表示還有多少數據可以存儲或讀取,position<=limit

capacity:表示緩沖區的最大容量,limit<=capacity,此值在分配緩沖區時被設置。一般不改變。

創建緩沖區:

importjava.nio.IntBuffer ;public classIntBufferDemo{public static voidmain(String args[]){

IntBuffer buf= IntBuffer.allocate(10) ; //準備出10個大小的緩沖區

System.out.print("1、寫入數據之前的position、limit和capacity:") ;

System.out.println("position = " + buf.position() + ",limit = " + buf.limit() + ",capacty = " +buf.capacity()) ;int temp[] = {5,7,9} ;//定義一個int數組

buf.put(3) ; //設置一個數據

buf.put(temp) ; //此時已經存放了四個記錄

System.out.print("2、寫入數據之后的position、limit和capacity:") ;

System.out.println("position = " + buf.position() + ",limit = " + buf.limit() + ",capacty = " +buf.capacity()) ;

buf.flip() ;//重設緩沖區//postion = 0 ,limit = 原本position

System.out.print("3、準備輸出數據時的position、limit和capacity:") ;

System.out.println("position = " + buf.position() + ",limit = " + buf.limit() + ",capacty = " +buf.capacity()) ;

System.out.print("緩沖區中的內容:") ;while(buf.hasRemaining()){int x =buf.get() ;

System.out.print(x+ "、") ;

}

}

}

如果創建了緩沖區,則JVM可直接對其執行本機的IO操作

importjava.nio.ByteBuffer ;public classByteBufferDemo{public static voidmain(String args[]){

ByteBuffer buf= ByteBuffer.allocateDirect(10) ; //準備出10個大小的緩沖區

byte temp[] = {1,3,5,7,9} ; //設置內容

buf.put(temp) ; //設置一組內容

buf.flip() ;

System.out.print("主緩沖區中的內容:") ;while(buf.hasRemaining()){int x =buf.get() ;

System.out.print(x+ "、") ;

}

}

}

通道(Channel)

Java NIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什么都不會獲取。而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可以繼續做其他的事情。 非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。 線程通常將非阻塞IO的空閑時間用于在其它通道上執行IO操作,所以一個單獨的線程現在可以管理多個輸入和輸出通道(channel)。

Java NIO的通道類似流,但又有些不同:

既可以從通道中讀取數據,又可以寫數據到通道。但流的讀寫通常是單向的。

通道可以異步地讀寫。

通道中的數據總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。

正如上面所說,從通道讀取數據到緩沖區,從緩沖區寫入數據到通道。

Channel的實現

這些是Java NIO中最重要的通道的實現:

FileChannel

DatagramChannel

SocketChannel

ServerSocketChannel

FileChannel 從文件中讀寫數據。

DatagramChannel 能通過UDP讀寫網絡中的數據。

SocketChannel 能通過TCP讀寫網絡中的數據。

ServerSocketChannel可以監聽新進來的TCP連接,像Web服務器那樣。對每一個新進來的連接都會創建一個SocketChannel。

通過通道可以完成雙向的輸入和輸出操作。在通道還有一種方式稱為內存映射

幾種讀入的方式的比較

RandomAccessFile 較慢

FileInputStream 較慢

緩沖讀取      速度較快

內存映射      速度最快

FileChannel內存映射實例

importjava.nio.ByteBuffer ;importjava.nio.MappedByteBuffer ;importjava.nio.channels.FileChannel ;importjava.io.File ;importjava.io.FileOutputStream ;importjava.io.FileInputStream ;public classFileChannelDemo03{public static void main(String args[]) throwsException{

File file= new File("d:" + File.separator + "oumyye.txt") ;

FileInputStream input= null;

input= newFileInputStream(file) ;

FileChannel fin= null ; //定義輸入的通道

fin = input.getChannel() ; //得到輸入的通道

MappedByteBuffer mbb = null;

mbb= fin.map(FileChannel.MapMode.READ_ONLY,0,file.length()) ;byte data[] = new byte[(int)file.length()] ; //開辟空間接收內容

int foot = 0;while(mbb.hasRemaining()){

data[foot++] = mbb.get() ; //讀取數據

}

System.out.println(new String(data)) ; //輸出內容

fin.close() ;

input.close() ;

}

}

操作以上代碼的時候,執行的是寫入操作則可能是非常危險的,因為僅僅只是改變數組中的單個元素這種簡單的操作,就可能直接修改磁盤上的文件,因為修改數據與數據保存在磁盤上是一樣的。

選擇器(Selectors)

Selector(選擇器)是Java NIO中能夠檢測一到多個NIO通道,并能夠知曉通道是否為諸如讀寫事件做好準備的組件。這樣,一個單獨的線程可以管理多個channel,從而管理多個網絡連接。

為什么使用Selector?

僅用單個線程來處理多個Channels的好處是,只需要更少的線程來處理通道。事實上,可以只用一個線程處理所有的通道。對于操作系統來說,線程之間上下文切換的開銷很大,而且每個線程都要占用系統的一些資源(如內存)。因此,使用的線程越少越好。

但是,需要記住,現代的操作系統和CPU在多任務方面表現的越來越好,所以多線程的開銷隨著時間的推移,變得越來越小了。實際上,如果一個CPU有多個內核,不使用多任務可能是在浪費CPU能力。不管怎么說,關于那種設計的討論應該放在另一篇不同的文章中。在這里,只要知道使用Selector能夠處理多個通道就足夠了。

要點

使用Selector可以構建一個非阻塞的網絡服務。

在新IO實現網絡程序需要依靠ServerSocketChannel類與SocketChannel

Selector實例

下面使用Selector完成一個簡單的服務器的操作,服務器可以同時在多個端口進行監聽,此服務器的主要功能是返回當前時間。

importjava.net.InetSocketAddress ;importjava.net.ServerSocket ;importjava.util.Set ;importjava.util.Iterator ;importjava.util.Date ;importjava.nio.channels.ServerSocketChannel ;importjava.nio.ByteBuffer ;importjava.nio.channels.SocketChannel ;importjava.nio.channels.Selector ;importjava.nio.channels.SelectionKey ;public classDateServer{public static void main(String args[]) throwsException {int ports[] = {8000,8001,8002,8003,8005,8006} ; //表示五個監聽端口

Selector selector = Selector.open() ; //通過open()方法找到Selector

for(int i=0;i

ServerSocketChannel initSer= null;

initSer= ServerSocketChannel.open() ; //打開服務器的通道

initSer.configureBlocking(false) ; //服務器配置為非阻塞

ServerSocket initSock =initSer.socket() ;

InetSocketAddress address= null;

address= new InetSocketAddress(ports[i]) ; //實例化綁定地址

initSock.bind(address) ; //進行服務的綁定

initSer.register(selector,SelectionKey.OP_ACCEPT) ; //等待連接

System.out.println("服務器運行,在" + ports[i] + "端口監聽。") ;

}//要接收全部生成的key,并通過連接進行判斷是否獲取客戶端的輸出

int keysAdd = 0;while((keysAdd=selector.select())>0){ //選擇一組鍵,并且相應的通道已經準備就緒

Set selectedKeys = selector.selectedKeys() ;//取出全部生成的key

Iterator iter =selectedKeys.iterator() ;while(iter.hasNext()){

SelectionKey key= iter.next() ; //取出每一個key

if(key.isAcceptable()){

ServerSocketChannel server=(ServerSocketChannel)key.channel() ;

SocketChannel client= server.accept() ; //接收新連接

client.configureBlocking(false) ;//配置為非阻塞

ByteBuffer outBuf = ByteBuffer.allocateDirect(1024) ; // outBuf.put(("當前的時間為:" + new Date()).getBytes()) ; //向緩沖區中設置內容

outBuf.flip() ;

client.write(outBuf) ;//輸出內容

client.close() ; //關閉

}

}

selectedKeys.clear() ;//清楚全部的key

}

}

}

服務器完成之后可以使用Telnet命令完成,這樣就完成了一個一部的操作服務器。

總結

以上是生活随笔為你收集整理的xnio java_java基础篇---新I/O技术(NIO)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。