1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      JavaNIO是什么

      這篇文章主要介紹Java NIO是什么,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

      10年積累的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)制作后付款的網(wǎng)站建設(shè)流程,更有臨川免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

      Java NIO主要需要理解緩沖區(qū)、通道、選擇器三個(gè)核心概念,作為對Java I/O的補(bǔ)充, 以提升大批量數(shù)據(jù)傳輸?shù)男省?/p>

      學(xué)習(xí)NIO之前最好能有基礎(chǔ)的網(wǎng)絡(luò)編程知識(shí)

      Java I/O流

      Java 網(wǎng)絡(luò)編程

      Java NIO:緩沖區(qū)

      通道(Channel)作為NIO的三大核心概念之一(緩沖區(qū)、通道、選擇器),用于在字節(jié)緩沖區(qū)與位于通道另一側(cè)的實(shí)體(文件或者套接字)之間有效的傳輸數(shù)據(jù)(核心是傳輸數(shù)據(jù))

      NIO編程的一般模式是:把數(shù)據(jù)填充到發(fā)送字節(jié)緩沖區(qū) --> 通過通道發(fā)送到通道對端文件或者套接字

      通道基礎(chǔ)

      使用Channel的目的是進(jìn)行數(shù)據(jù)傳輸,使用前需要打開通道、使用后需要關(guān)閉通道

      打開通道

      我們知道I/O有兩大類:File IO和 Stream I/O,其對應(yīng)到通道也就有文件通道(FileChannel)和套接字通道(SocketChannel、ServerSocketChannel、DatagramChannel)兩種

      對于套接字通道,使用靜態(tài)工廠方法打開

      SocketChannel sc = SocketChannel.open();
      ServerSocketChannel sc = ServerSocketChannel.open();
      DatagramChannel sc = DatagramChannel.open();

      對于文件通道只能通過對一個(gè)RandomAccessFile、FileInputStream、FileOutputStream對象調(diào)用getChannel()方法獲取

      FileInputStream in = new FileInputStream("/tmp/a.txt");
      FileChannel fc = in.getChannel();

      使用通道進(jìn)行數(shù)據(jù)傳輸

      下段代碼首先將要寫入的數(shù)據(jù)放到ByteBuffer中, 然后打開文件通道,把緩沖區(qū)中的數(shù)據(jù)放到文件通道。

      //準(zhǔn)備數(shù)據(jù)并放入字節(jié)緩沖區(qū)
      ByteBuffer bf = ByteBuffer.allocate(1024);
      bf.put("i am cool".getBytes());
      bf.flip();
      //打開文件通道
      FileOutputStream out = new FileOutputStream("/tmp/a.txt");
      FileChannel fc = out.getChannel();
      //數(shù)據(jù)傳輸
      fc.write(bf);
      //關(guān)閉通道
      fc.close();

      關(guān)閉通道

      如同Socket、FileInputStream等對象使用完畢之后需要關(guān)閉一樣, 通道使用之后也需要關(guān)閉。一個(gè)打開的通道代表與一個(gè)特定I/O服務(wù)的特定連接并封裝該連接的狀態(tài),通道關(guān)閉時(shí)連接丟失,不再連接任何東西。

      阻塞 & 非阻塞模式

      通道有阻塞和非阻塞兩種運(yùn)行模式,非阻塞模式的通道永遠(yuǎn)不會(huì)休眠,請求的操作要么立即完成,要么返回一個(gè)結(jié)果表明未進(jìn)行任何操作(具體看Socket通道處的描述)。只有面向流的通道可使用非阻塞模式

      文件通道

      文件通道用于對文件進(jìn)行訪問, 通過對一個(gè)RandomAccessFile、FileInputStream、FileOutputStream對象調(diào)用getChannel()方法獲取。調(diào)用getChannel方法返回一個(gè)連接到相同文件的FileChannel對象,該FileChannel對象具有與file對象相同的訪問權(quán)限。

      文件訪問

      使用文件通道的目的還是對文件進(jìn)行讀寫操作,通道的讀寫api如下:

      public abstract int read(ByteBuffer dst) throws IOException;
      public abstract int write(ByteBuffer src) throws IOException;

      下面是一段讀取文件的Demo

      //打開文件channel
      RandomAccessFile f = new RandomAccessFile("/tmp/a.txt", "r");
      FileChannel fc = f.getChannel();
      //從channel中讀取數(shù)據(jù),直到文件尾
      ByteBuffer bb = ByteBuffer.allocate(1024);
      while (fc.read(bb) != -1) {
      ;
      }
      //翻轉(zhuǎn)(讀之前需要先進(jìn)行翻轉(zhuǎn))
      bb.flip();
      StringBuilder builder = new StringBuilder();
      //把每一個(gè)字節(jié)轉(zhuǎn)為字符(ascii編碼)
      while (bb.hasRemaining()) {
      builder.append((char) bb.get());
      }
      System.out.println(builder.toString());

      上面這個(gè)demo有個(gè)問題:我們只能讀取字節(jié), 然后由應(yīng)用程序去解碼,這個(gè)問題我們可以通過工具類Channels將通道包裝成Reader和Writer來解決;當(dāng)然我們也可以直接使用Java I/O流模式的Reader和Writer操作字符

      文件通道位置與文件空洞

      文件通道位置(position)就是普通文件的位置, position的值決定了文件中哪個(gè)位置的數(shù)據(jù)接下來將被讀或者寫

      讀取超出文件尾部位置的數(shù)據(jù)會(huì)返回-1(文件EOF)

      往一個(gè)超出文件尾部的位置寫入數(shù)據(jù)會(huì)造成文件空洞:比如一個(gè)文件現(xiàn)在有10個(gè)字節(jié), 但是此時(shí)往position=20 處寫入數(shù)據(jù)就會(huì)造成10~20之間的位置是沒有數(shù)據(jù)的,這就是文件空洞

      force操作

      force操作強(qiáng)制通道將全部修改立即應(yīng)用到磁盤文件(防止系統(tǒng)宕機(jī)導(dǎo)致修改丟失)

      public abstract void force(boolean metaData) throws IOException;

      內(nèi)存文件映射

      FileChannel提供了一個(gè)map()方法,該方法可以在一個(gè)打開的文件和特殊類型的ByteBuffer(MappedByteBuffer)之間建立一個(gè)虛擬內(nèi)存映射。

      因?yàn)閙ap方法返回的MappedByteBuffer對象是直接緩沖區(qū),所以通過MappedByteBuffer來操作文件非常高效(尤其是大量數(shù)據(jù)傳輸?shù)那闆r)

      MappedByteBuffer的使用

      通過MappedByteBuffer讀取文件

      FileInputStream in = new FileInputStream("/tmp/a.txt");
      FileChannel fc = in.getChannel();
      MappedByteBuffer mbb = fc.map(MapMode.READ_ONLY, 0, fc.size());
      StringBuilder builder = new StringBuilder();
      while (mbb.hasRemaining()) {
        builder.append((char) mbb.get());
      }
      System.out.println(builder.toString());

      MappedByteBuffer的三種模式

      READ_ONLY

      READ_WRITE

      PRIVATE

      只讀和讀寫模式都好理解,PRIVATE模式下寫操作寫的是一個(gè)臨時(shí)緩沖區(qū),不會(huì)真正去寫文件。(寫時(shí)拷貝思想)

      Socket通道

      Socket 通道可以運(yùn)行在非阻塞模式且是可選擇的,這兩點(diǎn)使得對于網(wǎng)絡(luò)編程我們不再需要為每個(gè)Socket連接創(chuàng)建一個(gè)線程,而是使用一個(gè)線程即可管理成百上千的Socket連接。

      所有的Socket通道在實(shí)例化的時(shí)候都會(huì)創(chuàng)建一個(gè)對象的Socket對象, Socket通道并不負(fù)責(zé)協(xié)議相關(guān)的操作, 協(xié)議相關(guān)的操作都委派給對等socket對象(如SocketChannel對象委派給Socket對象)

      非阻塞模式

      相較于傳統(tǒng)Java Socket的阻塞模式,SocketChannel提供了非阻塞模式,以構(gòu)建高性能的網(wǎng)絡(luò)應(yīng)用程序

      非阻塞模式下,幾乎所有的操作都是立刻返回的。比如下面的SocketChannel運(yùn)行在非阻塞模式下,connect操作會(huì)立即返回,如果success為true代表連接已經(jīng)建立成功了, 如果success為false, 代表連接還在建立中(tcp連接需要一些時(shí)間)。

       //打開Socket通道
       SocketChannel ch = SocketChannel.open();
       //非阻塞模式
       ch.configureBlocking(false);
       //連接服務(wù)器 
       boolean success = ch.connect(InetSocketAddress.createUnresolved("127.0.0.1", 7001));
       //輪訓(xùn)連接狀態(tài), 如果連接還未建立就可以做一些別的工作
       while (!ch.finishConnect()){
          //dosomething else
       }
       //連接建立, 做正事
       //do something;

      ServerSocketChannel

      ServerSocketChannel與ServerSocket類似,只是可以運(yùn)行在非阻塞模式下

      下為一個(gè)通過ServerSocketChannel構(gòu)建服務(wù)器的簡單例子,主要體現(xiàn)了非阻塞模式,核心思想與ServerSocket類似

      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking(false);
      ssc.bind(new InetSocketAddress(7001));
      while (true){
        SocketChannel sc = ssc.accept();
        if(sc != null){
          handle(sc);
        }else {
          Thread.sleep(1000);
        }
      }

      SocketChannel 與 DatagramChannel

      SocketChannel 對應(yīng) Socket, 模擬TCP協(xié)議;DatagramChannel對應(yīng)DatagramSocket, 模擬UDP協(xié)議

      二者的使用與SeverSocketChannel大同小異,看API即可

      工具類

      文體通道那里我們提到過, 通過只能操作字節(jié)緩沖區(qū), 編解碼需要應(yīng)用程序自己實(shí)現(xiàn)。如果我們想在通道上直接操作字符,我們就需要使用工具類Channels,工具類Channels提供了通道與流互相轉(zhuǎn)換、通道轉(zhuǎn)換為閱讀器書寫器的能力,具體API入下

      //通道 --> 輸入輸出流
      public static OutputStream newOutputStream(final WritableByteChannel ch);
      public static InputStream newInputStream(final AsynchronousByteChannel ch);
      //輸入輸出流 --> 通道
      public static ReadableByteChannel newChannel(final InputStream in);
      public static WritableByteChannel newChannel(final OutputStream out);
      //通道  --> 閱讀器書寫器
      public static Reader newReader(ReadableByteChannel ch, String csName);
      public static Writer newWriter(WritableByteChannel ch, String csName);

      通過將通道轉(zhuǎn)換為閱讀器、書寫器我們就可以直接在通道上操作字符。

          RandomAccessFile f = new RandomAccessFile("/tmp/a.txt", "r");
        FileChannel fc = f.getChannel();
        //通道轉(zhuǎn)換為閱讀器,UTF-8編碼
        Reader reader = Channels.newReader(fc, "UTF-8");
        int i = 0, s = 0;
        char[] buff = new char[1024];
        while ((i = reader.read(buff, s, 1024 - s)) != -1) {
          s += i;
        }
        for (i = 0; i < s; i++) {
          System.out.print(buff[i]);
        }

      總結(jié)

      通道主要分為文件通道和套接字通道。

      對于文件操作:如果是大文件使用通道的文件內(nèi)存映射特性(MappedByteBuffer)來有利于提升傳輸性能, 否則我更傾向傳統(tǒng)的I/O流模式(字符API);對于套接字操作, 使用通道可以運(yùn)行在非阻塞模式并且是可選擇的,利于構(gòu)建高性能網(wǎng)絡(luò)應(yīng)用程序。

      以上是Java NIO是什么的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


      本文名稱:JavaNIO是什么
      分享URL:http://www.ef60e0e.cn/article/psdded.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        岐山县| 鹤壁市| 阿尔山市| 鲁山县| 辛集市| 西安市| 衡南县| 得荣县| 会同县| 武平县| 荔浦县| 霍林郭勒市| 颍上县| 朝阳县| 原阳县| 乾安县| 进贤县| 四会市| 兴城市| 德江县| 沽源县| 勐海县| 石阡县| 太白县| 清徐县| 巴青县| 青阳县| 赤水市| 阳高县| 原平市| 南和县| 长阳| 普安县| 周至县| 长沙市| 恩施市| 合川市| 昂仁县| 集安市| 东台市| 临沂市|