国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java NIO 的前生今世 之二 NIO Channel 小結

JasonZhang / 2813人閱讀

摘要:通常來說所有的的操作都是從開始的一個類似于一個和對比我們可以在同一個中執行讀和寫操作然而同一個僅僅支持讀或寫可以異步地讀寫而是阻塞的同步讀寫總是從中讀取數據或將數據寫入到中類型有文件操作操作操作操作使用在服務器端這些通道涵蓋了和網絡以及文件

Java NIO Channel

通常來說, 所有的 NIO 的 I/O 操作都是從 Channel 開始的. 一個 channel 類似于一個 stream.
java Stream 和 NIO Channel 對比

我們可以在同一個 Channel 中執行讀和寫操作, 然而同一個 Stream 僅僅支持讀或寫.

Channel 可以異步地讀寫, 而 Stream 是阻塞的同步讀寫.

Channel 總是從 Buffer 中讀取數據, 或將數據寫入到 Buffer 中.

Channel 類型有:

FileChannel, 文件操作

DatagramChannel, UDP 操作

SocketChannel, TCP 操作

ServerSocketChannel, TCP 操作, 使用在服務器端.
這些通道涵蓋了 UDP 和 TCP網絡 IO以及文件 IO.

基本的 Channel 使用例子:

public static void main( String[] args ) throws Exception
{
    RandomAccessFile aFile = new RandomAccessFile("/Users/xiongyongshun/settings.xml", "rw");
    FileChannel inChannel = aFile.getChannel();

    ByteBuffer buf = ByteBuffer.allocate(48);

    int bytesRead = inChannel.read(buf);
    while (bytesRead != -1) {
        buf.flip();

        while(buf.hasRemaining()){
            System.out.print((char) buf.get());
        }

        buf.clear();
        bytesRead = inChannel.read(buf);
    }
    aFile.close();
}
FileChannel

FileChannel 是操作文件的Channel, 我們可以通過 FileChannel 從一個文件中讀取數據, 也可以將數據寫入到文件中.
注意, FileChannel 不能設置為非阻塞模式.

打開 FileChannel
RandomAccessFile aFile     = new RandomAccessFile("test.txt", "rw");
FileChannel      inChannel = aFile.getChannel();
從 FileChannel 中讀取數據
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
寫入數據
String newData = "New String to write to file..." + System.currentTimeMillis();

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()) {
    channel.write(buf);
}
關閉

當我們對 FileChannel 的操作完成后, 必須將其關閉

channel.close(); 
設置 position
long pos channel.position();
channel.position(pos +123);
文件大小

我們可以通過 channel.size()獲取關聯到這個 Channel 中的文件的大小. 注意, 這里返回的是文件的大小, 而不是 Channel 中剩余的元素個數.

截斷文件
channel.truncate(1024);

將文件的大小截斷為1024字節.

強制寫入

我們可以強制將緩存的未寫入的數據寫入到文件中:

channel.force(true);
SocketChannel

SocketChannel 是一個客戶端用來進行 TCP 連接的 Channel.
創建一個 SocketChannel 的方法有兩種:

打開一個 SocketChannel, 然后將其連接到某個服務器中

當一個 ServerSocketChannel 接受到連接請求時, 會返回一個 SocketChannel 對象.

打開 SocketChannel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://example.com", 80));
關閉
socketChannel.close(); 
讀取數據
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = socketChannel.read(buf);

如果 read()返回 -1, 那么表示連接中斷了.

寫入數據
String newData = "New String to write to file..." + System.currentTimeMillis();

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()) {
    channel.write(buf);
}
非阻塞模式

我們可以設置 SocketChannel 為異步模式, 這樣我們的 connect, read, write 都是異步的了.

連接
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://example.com", 80));

while(! socketChannel.finishConnect() ){
    //wait, or do something else...    
}

在異步模式中, 或許連接還沒有建立, connect 方法就返回了, 因此我們需要檢查當前是否是連接到了主機, 因此通過一個 while 循環來判斷.

讀寫

在異步模式下, 讀寫的方式是一樣的.
在讀取時, 因為是異步的, 因此我們必須檢查 read 的返回值, 來判斷當前是否讀取到了數據.

ServerSocketChannel

ServerSocketChannel 顧名思義, 是用在服務器為端的, 可以監聽客戶端的 TCP 連接, 例如:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept();

    //do something with socketChannel...
}
打開 關閉
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.close();
監聽連接

我們可以使用ServerSocketChannel.accept()方法來監聽客戶端的 TCP 連接請求, accept()方法會阻塞, 直到有連接到來, 當有連接時, 這個方法會返回一個 SocketChannel 對象:

while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept();

    //do something with socketChannel...
}
非阻塞模式

在非阻塞模式下, accept()是非阻塞的, 因此如果此時沒有連接到來, 那么 accept()方法會返回null:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);

while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept();

    if(socketChannel != null){
        //do something with socketChannel...
        }
}
DatagramChannel

DatagramChannel 是用來處理 UDP 連接的.

打開
DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9999));
讀取數據
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();

channel.receive(buf);
發送數據
String newData = "New String to write to file..."
                    + System.currentTimeMillis();
    
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();

int bytesSent = channel.send(buf, new InetSocketAddress("example.com", 80));
連接到指定地址

因為 UDP 是非連接的, 因此這個的 connect 并不是向 TCP 一樣真正意義上的連接, 而是它會講 DatagramChannel 鎖住, 因此我們僅僅可以從指定的地址中讀取或寫入數據.

channel.connect(new InetSocketAddress("example.com", 80));

本文由 yongshun 發表于個人博客, 采用署名-非商業性使用-相同方式共享 3.0 中國大陸許可協議.
非商業轉載請注明作者及出處. 商業轉載請聯系作者本人
Email: yongshun1228@gmail.com
本文標題為: Java NIO 的前生今世 之二 NIO Channel 小結
本文鏈接為: segmentfault.com/a/1190000006824107

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65102.html

相關文章

  • Netty 源碼分析之 一 揭開 Bootstrap 神秘紅蓋頭 (客戶端)

    摘要:目錄源碼分析之番外篇的前生今世的前生今世之一簡介的前生今世之二小結的前生今世之三詳解的前生今世之四詳解源碼分析之零磨刀不誤砍柴工源碼分析環境搭建源碼分析之一揭開神秘的紅蓋頭源碼分析之一揭開神秘的紅蓋頭客戶端源碼分析之一揭開神秘的紅蓋頭服務器 目錄 Netty 源碼分析之 番外篇 Java NIO 的前生今世 Java NIO 的前生今世 之一 簡介 Java NIO 的前生今世 ...

    zhaot 評論0 收藏0
  • 源碼之下無秘密 ── 做最好 Netty 源碼分析教程

    摘要:背景在工作中雖然我經常使用到庫但是很多時候對的一些概念還是處于知其然不知其所以然的狀態因此就萌生了學習源碼的想法剛開始看源碼的時候自然是比較痛苦的主要原因有兩個第一網上沒有找到讓我滿意的詳盡的源碼分析的教程第二我也是第一次系統地學習這么大代 背景 在工作中, 雖然我經常使用到 Netty 庫, 但是很多時候對 Netty 的一些概念還是處于知其然, 不知其所以然的狀態, 因此就萌生了學...

    shenhualong 評論0 收藏0
  • Netty 源碼分析之 一 揭開 Bootstrap 神秘紅蓋頭 (服務器端)

    摘要:目錄源碼分析之番外篇的前生今世的前生今世之一簡介的前生今世之二小結的前生今世之三詳解的前生今世之四詳解源碼分析之零磨刀不誤砍柴工源碼分析環境搭建源碼分析之一揭開神秘的紅蓋頭源碼分析之一揭開神秘的紅蓋頭客戶端源碼分析之一揭開神秘的紅蓋頭服務器 目錄 Netty 源碼分析之 番外篇 Java NIO 的前生今世 Java NIO 的前生今世 之一 簡介 Java NIO 的前生今世 ...

    張金寶 評論0 收藏0
  • Netty 源碼分析之 三 我就是大名鼎鼎 EventLoop(一)

    摘要:目錄源碼之下無秘密做最好的源碼分析教程源碼分析之番外篇的前生今世的前生今世之一簡介的前生今世之二小結的前生今世之三詳解的前生今世之四詳解源碼分析之零磨刀不誤砍柴工源碼分析環境搭建源碼分析之一揭開神秘的紅蓋頭源碼分析之一揭開神秘的紅蓋頭客戶端 目錄 源碼之下無秘密 ── 做最好的 Netty 源碼分析教程 Netty 源碼分析之 番外篇 Java NIO 的前生今世 Java NI...

    livem 評論0 收藏0
  • Java NIO 前生今世 之一 簡介

    摘要:簡介是由引進的異步由以下幾個核心部分組成和的對比和的區別主要體現在三個方面基于流而基于操作是阻塞的而操作是非阻塞的沒有概念而有概念基于與基于傳統的是面向字節流或字符流的而在中我們拋棄了傳統的流而是引入了和的概念在中我只能從中讀取數據到中或將 簡介 Java NIO 是由 Java 1.4 引進的異步 IO.Java NIO 由以下幾個核心部分組成: Channel Buffer Se...

    李義 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<