還在被Java NIO虐?該試試Netty了

2020-11-06 smile蒲公英QQ

一、前言

Netty是一個開源的異步事件驅動的網絡應用程式框架,用於快速開發可維護的高性能協議伺服器和客戶端。

Netty的創始人是韓國人trustin lee,他現在韓國line公司工作,早前應用較多的Mina也是這牛人的作品。

Netty目前的項目leader是德國人Norman maurer(之前在Redhat,全職開發Netty),也是《Netty in action》的作者,目前是蘋果公司高級工程師,同時也經常參加netty相關的技術會議,這兩大牛長下面這樣:

Netty的優點,簡單一句話:使用簡單、功能強大、性能強悍

Netty的特點:

高並發:Netty 是一款基於 NIO(Nonblocking IO,非阻塞IO)開發的網絡通信框架,對比於 BIO(Blocking I/O,阻塞IO),它的並發性能得到了很大提高。

傳輸快:Netty 的傳輸依賴於零拷貝特性,儘量減少不必要的內存拷貝,實現了更高效率的傳輸。

封裝好:Netty 封裝了 NIO 操作的很多細節,提供了易於使用調用接口。

Netty的優勢:

使用簡單:封裝了 NIO 的很多細節,使用更簡單。

功能強大:預置了多種編解碼功能,支持多種主流協議。

定製能力強:可以通過 ChannelHandler 對通信框架進行靈活的擴展。

性能高:通過與其他業界主流的 NIO 框架對比,Netty 的綜合性能最優。

穩定:Netty 修復了已經發現的所有 NIO 的 bug,讓開發人員可以專注於業務本身。

社區活躍:Netty 是活躍的開源項目,版本迭代周期短,bug 修復速度快。

Netty高性能表現在哪些方面?

IO 線程模型:同步非阻塞,用最少的資源做更多的事。

內存零拷貝:儘量減少不必要的內存拷貝,實現了更高效率的傳輸。

內存池設計:申請的內存可以重用,主要指直接內存。內部實現是用一顆二叉查找樹管理內存分配情況。

串形化處理讀寫:避免使用鎖帶來的性能開銷。

高性能序列化協議:支持 protobuf 等高性能序列化協議。

BIO、NIO和AIO的區別是什麼?
這三個概念分別對應三種通訊模型:阻塞、非阻塞、非阻塞異步,概念這裡就不寫了,大家可以度娘搜一下,網上好多博客說Netty對應NIO,準確來說,應該是既可以是NIO,也可以是AIO,就看你怎麼實現,這三個的區別如下:

BIO:一個連接一個線程,客戶端有連接請求時伺服器端就需要啟動一個線程進行處理,線程開銷大。偽異步IO:將請求連接放入線程池,一對多,但線程還是很寶貴的資源。

NIO:一個請求一個線程,但客戶端發送的連接請求都會註冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。

AIO:一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動線程進行處理。

BIO是面向流的,NIO是面向緩衝區的;BIO的各種流是阻塞的。而NIO是非阻塞的;BIO的Stream是單向的,而NIO的channel是雙向的。

NIO的特點:事件驅動模型、單線程處理多任務、非阻塞I/O,I/O讀寫不再阻塞,而是返回0、基於block的傳輸比基於流的傳輸更高效、更高級的IO函數zero-copy、IO多路復用大大提高了Java網絡應用的可伸縮性和實用性。基於Reactor線程模型。

二、Netty能做什麼?

學技能都是為了能夠應用到實際工作中去,誰也不是為了學而學、弄著玩不是,那麼Netty能做什麼呢?主要是在兩個方面:

  • 現在物聯網的應用無處不在,大量的項目都牽涉到應用傳感器和伺服器端的數據通信,Netty作為基礎通信組件、能夠輕鬆解決之前有較高門檻的通信系統開發,你不用再為如何解析各類簡單、或複雜的通訊協議而薅頭髮了,有過這方面開發經驗的程式設計師會有更深刻、或者說刻骨銘心的體會。
  • 現在網際網路系統講究的都是高並發、分布式、微服務,各類消息滿天飛,Netty在這類架構裡面的應用可謂是如魚得水,如果你對當前的各種應用伺服器不爽,那麼完全可以基於Netty來實現自己的HTTP伺服器,FTP伺服器,UDP伺服器,RPC伺服器,WebSocket伺服器,Redis的Proxy伺服器,MySQL的Proxy伺服器等等。

三、掌握Netty有什麼好處呢?

直接的好處是:能夠有進大廠、拿高薪的機會,業內好多著名的公司在招聘高級/資深Java工程師時基本上都要求熟練掌握、或熟悉Netty。

這個名單還可以很長很長。。。

作為一個學Java的,如果沒有研究過Netty,那麼你對Java語言的使用和理解僅僅停留在表面水平,會點SSH,寫幾個MVC,訪問資料庫和緩存,這些只是初、中等Java程式設計師幹的事。如果你要進階,想了解Java伺服器的深層高階知識,Netty絕對是一個必須要過的門檻。

間接地好處是:多款開源框架中應用了Netty,掌握了Netty,就具有分析這些開源框架的基礎了,也就是有了成為技術大牛的基礎。

這些開源框架有哪些呢?簡單羅列一些典型的,如下:

阿里分布式服務框架 Dubbo 的 RPC 框架;

淘寶的消息中間件 RocketMQ;

Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架;

開源集群運算框架 Spark;

分布式計算框架 Storm;

並發應用和分布式應用 Akka;

名單依然很長很長。。。。

四、動手開幹、實現一個傳輸字符串的簡單實例

在開始動手之前,必要的基礎概念還是要知道的,要不然代碼敲下來,功能倒是實現了,但對Netty還是一頭霧水,這就不是本文要達到的目的了。

本示例需要用到的基礎知識主要有以下幾方面的東東,這些知識點最好有一個大概的了解,要不然,看實例會有一定的困難。

掌握Java基礎掌握Maven基礎熟悉IntelliJ IDEA集成開發工具的使用,這個工具簡稱IDEA知道TCP、Socket的基本概念

1、Netty的組件

I/O:各種各樣的流(文件、數組、緩衝、管道。。。)的處理(輸入輸出)。

Channel:通道,代表一個連接,每個Client請對會對應到具體的一個Channel。

ChannelPipeline:責任鏈,每個Channel都有且僅有一個ChannelPipeline與之對應,裡面是各種各樣的Handler。

handler:用於處理出入站消息及相應的事件,實現我們自己要的業務邏輯。

EventLoopGroup:I/O線程池,負責處理Channel對應的I/O事件。

ServerBootstrap:伺服器端啟動輔助對象。

Bootstrap:客戶端啟動輔助對象。

ChannelInitializer:Channel初始化器。

ChannelFuture:代表I/O操作的執行結果,通過事件機制,獲取執行結果,通過添加監聽器,執行我們想要的操作。

ByteBuf:字節序列,通過ByteBuf操作基礎的字節數組和緩衝區。

2、基礎環境準備

基礎環境準備主要有三個方面:JDK安裝及環境變量設置、Maven安裝及環境變量設置、IDEA安裝及基本設置。

2.1、JDK安裝及環境變量設置

JDK下載,可以從官方下載,也可以度娘上隨便搜下載連結,最新版是JDK14,我這裡下載的是JDK8,用8還是14哪個版本無所謂,都可以,但要注意一點的是,現在從JDK的官網Oracle下載需要帳號了,沒帳號的可下不了啦,不知道在搞什麼東東。
官網下載地址:https://www.oracle.com ,截圖如下:

下載完,一路Next安裝完,在創建Java環境變量設置,[此電腦]右鍵-->[屬性]-->[高級系統設置]-->[環境變量]-->[系統變量],截圖如下:

Java環境變量創建完畢後,在DOS窗口執行命令:java -version,測試一下是否正常

2.2、Maven安裝及環境變量設置

Maven功能很強大,但大家不用擔心、本實例中僅僅是利用其便利的jar包依賴、jar包依賴傳遞,基本上沒有任何學習成本。

jar包依賴、jar包依賴傳遞的概念如下圖,清楚明了,都不用多做解釋:

Maven是下載,解壓縮後,配置環境變量後就能用,不用安裝的。

下載地址https://downloads.apache.org/maven/maven-3/3.6.3/binaries/

安裝:下載壓縮包,解壓,文件夾拷貝到所想存儲的位置(如C盤根目錄)

配置環境變量,和Java的環境變量配置一樣的,創建MAVEN_HOME,指向Maven文件夾,再在path中添加進去就行,如下圖:

由於直接從Maven的中央倉庫中自動下載jar包較慢,一般在Maven的配置文件中,增加阿里雲的公共倉庫配置,這樣會顯著加快jar包的下載速度,如下:

上面的環境變量設置完後,通過DOS窗口中輸入命令:mvn -version 進行驗證是否成功,如下:

2.3、IDEA安裝及基本設置

IDEA的下載和安裝就不多說了,其版本分旗艦版和社區版,旗艦版收費,社區版免費,社區版不支持html、js、css等,但對於本實例,社區版就夠用了,但如果你不在乎那點銀子,可以考慮旗艦版,一步到位,萬一後面我們還要做WEB系統開發可以免得折騰。

其安裝不用多說,一路Next就行,安裝完後,在其配置裡面指定一下JDK、Maven的位置就行了,如下圖:
Maven指定:[File]-->[setting]-->[Build,Excution,Deployment]-->[Build Tools]-->[Maven】

JDK指定:[File]-->[Project Structure]-->[Project Setting]-->[Project]

3、在IDEA中創建Maven工程

新建工程

填寫包名及工程名稱

Maven配置

生成工程,自動創建Maven的依賴文件

在pom.xml中配置Netty依賴

經過上面的步驟,我們的Maven工程就已經創建完畢,現在可以編寫Netty的第一個程序,這個程序很簡單,傳輸一個字符串,雖然程序很簡單,但是已經能夠大體上反映Netty開發通信程序的一個整體流程了。

4、Netty開發的基本流程

Netty開發的基本流程很簡潔,伺服器端和客戶端都是這個套路,如下:

Netty開發的實際過程,這是一個簡化的過程,但已經把大概流程表達出來了,綠色的代表客戶端流程、藍色的代表伺服器端流程,注意標紅的部分,見下圖:

4.1 創建客戶端類

創建Handler

首先創建Handler類,該類用於接收伺服器端發送的數據,這是一個簡化的類,只重寫了消息讀取方法channelRead0、捕捉異常方法exceptionCaught。

客戶端的Handler一般繼承的是SimpleChannelInboundHandler,該類有豐富的方法,心跳、超時檢測、連接狀態等等。

代碼如下:

package com.jcj.helloworld;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.util.CharsetUtil;/** * @Auther: 江成軍 * @Date: 2020/6/1 11:12 * @Description: 通用handler,處理I/O事件 */@ChannelHandler.Sharablepublic class HandlerClientHello extends SimpleChannelInboundHandler<ByteBuf>{ @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { /** * @Author 江成軍 * @Date 2020/6/1 11:17 * @Description 處理接收到的消息 **/ System.out.println("接收到的消息:"+byteBuf.toString(CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { /** * @Author 江成軍 * @Date 2020/6/1 11:20 * @Description 處理I/O事件的異常 **/ cause.printStackTrace(); ctx.close(); }}

代碼說明:

@ChannelHandler.Sharable,這個註解是為了線程安全,如果你不在乎是否線程安全,不加也可以。

SimpleChannelInboundHandler,這裡的類型可以是ByteBuf,也可以是String,還可以是對象,根據實際情況來。

channelRead0,消息讀取方法,注意名稱中有個0。

ChannelHandlerContext,通道上下文,代指Channel。

ByteBuf,字節序列,通過ByteBuf操作基礎的字節數組和緩衝區,因為JDK原生操作字節麻煩、效率低,所以Netty對字節的操作進行了封裝,實現了指數級的性能提升,同時使用更加便利。

CharsetUtil.UTF_8,這個是JDK原生的方法,用於指定字節數組轉換為字符串時的編碼格式。

創建客戶端啟動類

客戶端啟動類根據伺服器端的IP和埠,建立連接,連接建立後,實現消息的雙向傳輸。

代碼較簡潔,如下:

package com.jcj.helloworld;import com.sun.org.apache.bcel.internal.generic.ATHROW;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.util.CharsetUtil;import java.net.InetSocketAddress;/** * @Auther: 江成軍 * @Date: 2020/6/1 11:24 * @Description: 客戶端啟動類 */public class AppClientHello{ private final String host; private final int port; public AppClientHello(String host, int port) { this.host = host; this.port = port; } public void run() throws Exception { /** * @Author 江成軍 * @Date 2020/6/1 11:28 * @Description 配置相應的參數,提供連接到遠端的方法 **/ EventLoopGroup group = new NioEventLoopGroup();//I/O線程池 try { Bootstrap bs = new Bootstrap();//客戶端輔助啟動類 bs.group(group) .channel(NioSocketChannel.class)//實例化一個Channel .remoteAddress(new InetSocketAddress(host,port)) .handler(new ChannelInitializer<SocketChannel>()//進行通道初始化配置 { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new HandlerClientHello());//添加我們自定義的Handler } }); //連接到遠程節點;等待連接完成 ChannelFuture future=bs.connect().sync(); //發送消息到伺服器端,編碼格式是utf-8 future.channel().writeAndFlush(Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)); //阻塞操作,closeFuture()開啟了一個channel的監聽器(這期間channel在進行各項工作),直到鏈路斷開 future.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { new AppClientHello("127.0.0.1",18080).run(); }}

由於代碼中已經添加了詳盡的注釋,這裡只對極個別的進行說明:

ChannelInitializer,通道Channel的初始化工作,如加入多個handler,都在這裡進行。

bs.connect().sync(),這裡的sync()表示採用的同步方法,這樣連接建立成功後,才繼續往下執行。

pipeline(),連接建立後,都會自動創建一個管道pipeline,這個管道也被稱為責任鏈,保證順序執行,同時又可以靈活的配置各類Handler,這是一個很精妙的設計,既減少了線程切換帶來的資源開銷、避免好多麻煩事,同時性能又得到了極大增強。

4.2 創建伺服器端類

創建Handler

和客戶端一樣,只重寫了消息讀取方法channelRead(注意這裡不是channelRead0)、捕捉異常方法exceptionCaught。

另外伺服器端Handler繼承的是ChannelInboundHandlerAdapter,而不是SimpleChannelInboundHandler,至於這兩者的區別,這裡不贅述,大家自行百度吧。

代碼如下:

package com.jcj.helloworld;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.util.CharsetUtil;/** * @Auther: 江成軍 * @Date: 2020/6/1 11:47 * @Description: 伺服器端I/O處理類 */@ChannelHandler.Sharablepublic class HandlerServerHello extends ChannelInboundHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //處理收到的數據,並反饋消息到到客戶端 ByteBuf in = (ByteBuf) msg; System.out.println("收到客戶端發過來的消息: " + in.toString(CharsetUtil.UTF_8)); //寫入並發送信息到遠端(客戶端) ctx.writeAndFlush(Unpooled.copiedBuffer("你好,我是服務端,我已經收到你發送的消息", CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { //出現異常的時候執行的動作(列印並關閉通道) cause.printStackTrace(); ctx.close(); }}

以上代碼很簡潔,大家注意和客戶端Handler類進行比較。

創建伺服器端啟動類

伺服器端啟動類比客戶端啟動類稍顯複雜一點,先貼出代碼如下:

package com.jcj.helloworld;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import java.net.InetSocketAddress;/** * @Auther: 江成軍 * @Date: 2020/6/1 11:51 * @Description: 伺服器端啟動類 */public class AppServerHello{ private int port; public AppServerHello(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup group = new NioEventLoopGroup();//Netty的Reactor線程池,初始化了一個NioEventLoop數組,用來處理I/O操作,如接受新的連接和讀/寫數據 try { ServerBootstrap b = new ServerBootstrap();//用於啟動NIO服務 b.group(group) .channel(NioServerSocketChannel.class) //通過工廠方法設計模式實例化一個channel .localAddress(new InetSocketAddress(port))//設置監聽埠 .childHandler(new ChannelInitializer<SocketChannel>() { //ChannelInitializer是一個特殊的處理類,他的目的是幫助使用者配置一個新的Channel,用於把許多自定義的處理類增加到pipline上來 @Override public void initChannel(SocketChannel ch) throws Exception {//ChannelInitializer 是一個特殊的處理類,他的目的是幫助使用者配置一個新的 Channel。 ch.pipeline().addLast(new HandlerServerHello());//配置childHandler來通知一個關於消息處理的InfoServerHandler實例 } }); //綁定伺服器,該實例將提供有關IO操作的結果或狀態的信息 ChannelFuture channelFuture= b.bind().sync(); System.out.println("在" + channelFuture.channel().localAddress()+"上開啟監聽"); //阻塞操作,closeFuture()開啟了一個channel的監聽器(這期間channel在進行各項工作),直到鏈路斷開 channelFuture.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync();//關閉EventLoopGroup並釋放所有資源,包括所有創建的線程 } } public static void main(String[] args) throws Exception { new AppServerHello(18080).run(); }

代碼說明:

EventLoopGroup,實際項目中,這裡創建兩個EventLoopGroup的實例,一個負責接收客戶端的連接,另一個負責處理消息I/O,這裡為了簡單展示流程,讓一個實例把這兩方面的活都幹了。

NioServerSocketChannel,通過工廠通過工廠方法設計模式實例化一個channel,這個在大家還沒有能夠熟練使用Netty進行項目開發的情況下,不用去深究。

到這裡,我們就把伺服器端和客戶端都寫完了 ,如何運行呢,先在伺服器端啟動類上右鍵,點Run 'AppServerHello.main()'菜單運行,見下圖:

然後,再同樣的操作,運行客戶端啟動類,就能看見效果了。

5、尾聲

本文的內容就到這裡結束了,希望本文能夠讓大家對Netty有一個整體的認識,並大概了解其開發流程。

Netty的功能很多,本文只是一個入門的介紹,如果大家對於Netty開發有興趣,可以關注我並給我留言,我會根據關注和留言情況,陸續再撰寫Netty實戰開發的文章。

得到肯定和正向反饋,才有繼續寫下去的願望和動力,畢竟寫這種事無巨細的文章,還是挺費精力的。

相關焦點

  • 大家都用 Netty,為什麼不用Java NIO?
    中間件開發中對IO及netty的設計?BIO,NIO,EPOLL,同步,異步,阻塞,非阻塞是一直圍繞程式設計師的問題,雖然優秀的框架,工具將這些點隱藏,但是,高素質,進大廠,突破薪資瓶頸都是需要對這些點準確理解。
  • Netty 3.2.4 Final 發布,NIO網絡框架
    netty  3.2.4 final 發布,距離上一個版本3.2.3 final 足足相隔了近3個月時間,不能不說netty  更新腳步變慢了。
  • 程式設計師:利用Netty來寫一個簡單的聊天室、心跳檢測
    *;import io.netty.channel.group.ChannelGroup;import io.netty.channel.group.DefaultChannelGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel
  • 當Tomcat遇上Netty
    (ByteToMessageDecoder.java:273) io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java
  • 彤哥說netty系列之Java NIO核心組件之Selector
    概念我們先來看兩段Selector的注釋,見類java.nio.channels.Selector。注釋IA multiplexor of {@link SelectableChannel} objects.
  • 終於有清華架構師從TCPNIO一直到Netty解釋的這麼清楚
    清晰明了,從nio獲取本次從清晰明了,從nio,epoll一直學到netty畫圖筆記、視頻、源碼等請關注我,私信回復「NIO」即可免費獲取如何獲取?轉發這篇文章,關注我,私信回復「NIO」即可獲取高清大綱,以上從nio,epoll一直學到netty畫圖筆記、視頻、源碼等課件如何私信?
  • 彤哥說netty系列之Java NIO核心組件之Channel
    你好,我是彤哥,本篇是netty系列的第五篇。Channel概念我們先來看看Java中對於Channel的定義,位於java.nio.channels.Channel類的注釋上:A nexus for I/O operations.
  • 網絡編程Netty IoT百萬長連接優化,萬字長文精講
    如果程序被中斷,或報了異常java.io.IOException: 設備上沒有空間 at sun.nio.ch.EPollArrayWrapper.epollCtl(Native Method) at sun.nio.ch.EPollArrayWrapper.updateRegistrations(EPollArrayWrapper.java
  • Netty學習前基本知識—BIO 、NIO 、AIO 總結
    ;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel
  • Netty實現高性能RPC伺服器優化篇之消息序列化
    在文章的最後提及到,其實基於該方案設計的RPC伺服器的處理性能,還有優化的餘地。於是利用周末的時間,在原來NettyRPC框架的基礎上,加以優化重構,本次主要優化改造點如下:1、NettyRPC中對RPC消息進行編碼、解碼採用的是Netty自帶的ObjectEncoder、ObjectDecoder(對象編碼、解碼器),該編碼、解碼器基於的是java的原生序列化機制,從已有的文章以及測試數據來看
  • Netty的使用:Client端
    Client端import java.net.InetSocketAddress;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import org.apache.commons.lang3.StringUtils;import org.apache.commons.logging.Log
  • Java-徹底弄懂netty-原來netty是這樣啟動的-知識鋪
    一、捋順netty開啟方式最簡單開啟一個server nio開啟具體流程:1.1 創建兩個NioEventLoopGroup對象這兩個對象是netty調度模塊,也相對於傳統I/O編程中的大線程組。 mainGroup:監聽埠,創建新連接的線程組。 workerGroup: 處理每條鏈路上的數據讀寫線程組。
  • 八、Netty入門服務端代碼
    4.等待一會選擇,Download to可以不用勾選,下載的jar會放在本地的jar倉庫裡,如果勾選了則會在該項目下創建一個在該項目的pom.xml裡加入netty依賴。 <!-- netty --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha2</version> </dependency>
  • Java NIO Path 接口和文件對象的轉換
    路徑接口位於 java.nio.file 包中,所以Java Path接口的完全包名是 java.nio.file.Path。java.io.File => java.nio.file.Path可以考察下面的代碼來對 Path 進行測試。
  • 深入理解Java NIO
    Java 類庫提供了相應的類來解決這些難題,這些類就位於 java.io 包中, 在整個 java.io 包中最重要的就是 5 2.5 Buffer 使用實例import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel
  • 什麼是Java NIO Path接口操作文件,如何操作使用?
    1、前言Path接口位於java.nio.file包中,所以Path接口的完全限定名稱為java.nio.file.Path。在許多方面,java.nio.file.Path接口類似於java.io.File類,但是有一些細微的差別。不過,在許多情況下,您可以使用Path接口來替換File類的使用。
  • IAVA高級開發-刨根問底netty源碼分析之writeAndFlush全解析
    前言在前面的文章中,我們已經詳細闡述了事件和異常傳播在netty中的實現,(netty源碼分析之pipeline(一),netty源碼分析之pipeline(二)),其中有一類事件我們在實際編碼中用得最多,那就是 write或者writeAndFlush,也就是我們今天的主要內容主要內容本文分以下幾個部分闡述一個
  • 小白科普:Netty有什麼用?
    中間件開發中對IO及netty的設計?netty很好很強大,也很靈活,框架中間件等都有它的影子,但是,很難有自己動手實現的機會,其實,netty也只不過是個io框架,io通信是分布式微服務中的基礎環節,向上直接構建不同風格的RPC實現。
  • Java NIO 核心組件全解
    無論任何情況,只要由寫操作轉換到讀操作,都需要先執行該方法。;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.
  • Java NIO - NIO與IO的比較
    原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html作者:Jakob Jenkov 譯者:郭蕾 校對:方騰飛這意味著,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了。 Java NIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什麼都不會獲取。而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可以繼續做其他的事情。 非阻塞寫也是如此。