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

資訊專(zhuān)欄INFORMATION COLUMN

基于零拷貝技術(shù)的的java NIO文件下載服務(wù)器

Keven / 2963人閱讀

摘要:什么是零拷貝我們首先來(lái)認(rèn)識(shí)一下傳統(tǒng)的操作。因?yàn)樵谶@套體系里,不僅僅提供了非阻塞的編程模型,而且提供了類(lèi)似零拷貝,內(nèi)存映射這樣的新技術(shù)對(duì)于操作系統(tǒng)來(lái)說(shuō)早就有了。

什么是零拷貝?
我們首先來(lái)認(rèn)識(shí)一下傳統(tǒng)的I/O操作
假如說(shuō)用戶進(jìn)程現(xiàn)在要把一個(gè)文件復(fù)制到另一個(gè)地方。
那么用戶程序必須先把這個(gè)文件讀入內(nèi)存,然后再把內(nèi)存里的數(shù)據(jù)寫(xiě)入另一個(gè)文件。
不過(guò)文件讀入內(nèi)存也不是直接讀入用戶進(jìn)程的內(nèi)存,而是先讀入操作系統(tǒng)內(nèi)核的內(nèi)存,然后再?gòu)牟僮飨到y(tǒng)內(nèi)核的內(nèi)存區(qū)讀到用戶進(jìn)程的內(nèi)存。
與之對(duì)應(yīng)的是,寫(xiě)文件也不是直接寫(xiě)到磁盤(pán)上的文件,而是用戶進(jìn)程先把自己內(nèi)存的數(shù)據(jù)傳到操作系統(tǒng)內(nèi)核的內(nèi)存,然后再?gòu)牟僮飨到y(tǒng)內(nèi)核的內(nèi)存區(qū)寫(xiě)到磁盤(pán)。而這其中涉及到諸多的系統(tǒng)調(diào)用
因此看上去簡(jiǎn)單的操作至少要分為四部
1磁盤(pán)文件讀入操作系統(tǒng)
2操作系統(tǒng)讀到用戶進(jìn)程
3用戶進(jìn)程寫(xiě)到操作系統(tǒng)
4操作系統(tǒng)寫(xiě)入磁盤(pán)文件

零拷貝和傳統(tǒng)I/O有和不同?
零拷貝就是指,傳輸一個(gè)文件的時(shí)候,不需要把文件讀到用戶進(jìn)程再處理,而是直接把文件讀到操作系統(tǒng)一個(gè)內(nèi)存區(qū),然后再移動(dòng)到操作系統(tǒng)的另一個(gè)內(nèi)存區(qū),最后寫(xiě)入文件。
這樣一來(lái),步驟變成這樣:
1磁盤(pán)文件讀入操作系統(tǒng)
2操作系統(tǒng)把數(shù)據(jù)寫(xiě)入操作系統(tǒng)另一個(gè)區(qū)域
3操作系統(tǒng)寫(xiě)入磁盤(pán)文件
雖然只少了一步,但是這里不僅減少了數(shù)據(jù)移動(dòng)的時(shí)間損耗,而且減少了系統(tǒng)調(diào)用的次數(shù),因此大大縮短了時(shí)間。
更加詳細(xì)的解釋請(qǐng)看https://blog.csdn.net/u010530...

java里如何實(shí)現(xiàn)零拷貝呢?
這就要說(shuō)起java nio中的FileChannel.transferTo()方法了,該方法是把FileChannel中的數(shù)據(jù)利用零靠的技術(shù)轉(zhuǎn)移到另一個(gè)channel。這另一個(gè)channel往往是FileChannel,不過(guò)SocketChannel也是可以的:)。
簡(jiǎn)單實(shí)現(xiàn)(靜態(tài)下載文件,不能根據(jù)用戶指令來(lái)更改下載的文件。)
代碼如下:
單線程版本:

package qiuqi.filedownloadtest;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;

public class FileServer {

    
    public static void main(String[] args) throws IOException {


        startServer();
    }

    public static void startServer() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(9999));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (selector.select() > 0)
        {
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext())
            {
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isAcceptable())
                {
                 SocketChannel socketChannel = serverSocketChannel.accept();
                 try (FileInputStream in = new FileInputStream("C:UsersdellDesktopOL手機(jī)數(shù)據(jù)(1).rar")){

                         long size = in.available();
                         long num = 0;
                         long begin = 0;
                         while ( (num = in.getChannel().transferTo(begin,size,socketChannel))!=0)
                         {
                             size-=num;
                             begin += num;
                         }
                     socketChannel.close();

                 }
                 catch (IOException e){e.printStackTrace();}

                }
            }
        }


    }
}


多線程版本:

package qiuqi.filedownloadtest;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileServer {

    static ExecutorService threadpool = Executors.newCachedThreadPool();
    public static void main(String[] args) throws IOException {

        startServer();
    }

    public static void startServer() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(9999));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (selector.select() > 0)
        {
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext())
            {
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isAcceptable())
                {
                 SocketChannel socketChannel = serverSocketChannel.accept();
                    threadpool.execute(new Runnable() {
                        @Override
                        public void run() {
                            try (FileInputStream in = new FileInputStream("C:UsersdellDesktopOL手機(jī)數(shù)據(jù)(1).rar")){

                         long size = in.available();
                         long num = 0;
                         long begin = 0;
                         while ( (num = in.getChannel().transferTo(begin,size,socketChannel))!=0)
                         {
                             size-=num;
                             begin += num;
                         }
                                socketChannel.close();
                            }
                            catch (IOException e){e.printStackTrace();}
                        }
                    });
                 

                }
            }
        }


    }
}

代碼就不講解了。如果學(xué)過(guò)java nio,那么理解上面的程序輕而易舉。
如果不熟悉java nio的服務(wù)器編程那么請(qǐng)先學(xué)習(xí)再來(lái)觀看。

最后我想說(shuō),java NIO真的是NEW IO即新的IO,而不是NonBlocking IO即非阻塞IO。因?yàn)樵谶@套體系里,不僅僅提供了非阻塞的編程模型,而且提供了類(lèi)似零拷貝,內(nèi)存映射這樣的新技術(shù)(對(duì)于操作系統(tǒng)來(lái)說(shuō)早就有了)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73543.html

相關(guān)文章

  • 徹底理解Netty,這一篇文章就夠了

    摘要:如果什么事都沒(méi)得做,它也不會(huì)死循環(huán),它會(huì)將線程休眠起來(lái),直到下一個(gè)事件來(lái)了再繼續(xù)干活,這樣的一個(gè)線程稱(chēng)之為線程。而請(qǐng)求處理邏輯既可以使用單獨(dú)的線程池進(jìn)行處理,也可以跟放在讀寫(xiě)線程一塊處理。 Netty到底是什么 從HTTP說(shuō)起 有了Netty,你可以實(shí)現(xiàn)自己的HTTP服務(wù)器,F(xiàn)TP服務(wù)器,UDP服務(wù)器,RPC服務(wù)器,WebSocket服務(wù)器,Redis的Proxy服務(wù)器,MySQL的P...

    yy13818512006 評(píng)論0 收藏0
  • MappedByteBuffer VS FileChannel 孰強(qiáng)孰弱?

    摘要:而每個(gè)文件系統(tǒng)又可以設(shè)置不同的調(diào)度算法,另外,還有虛擬內(nèi)存缺頁(yè)中斷帶來(lái)的性能毛刺良心的提供了調(diào)優(yōu)的腳本,這點(diǎn)做的不錯(cuò)跑題了。測(cè)試環(huán)境核線程內(nèi)存磁盤(pán)讀寫(xiě)左右虛擬內(nèi)存未關(guān)閉,大小測(cè)試注意點(diǎn)為了防止緩存的影響,每次都生成一個(gè)新的文件進(jìn)行讀取。 前言 Java 在 JDK 1.4 引入了 ByteBuffer 等 NIO 相關(guān)的類(lèi),使得 Java 程序員可以拋棄基于 Stream ,從而使用基...

    diabloneo 評(píng)論0 收藏0
  • Netty源碼解析

    摘要:一旦某個(gè)事件觸發(fā),相應(yīng)的則會(huì)被調(diào)用,并進(jìn)行處理。事實(shí)上,內(nèi)部的連接處理協(xié)議編解碼超時(shí)等機(jī)制,都是通過(guò)完成的。開(kāi)啟源碼之門(mén)理解了的事件驅(qū)動(dòng)機(jī)制,我們現(xiàn)在可以來(lái)研究的各個(gè)模塊了。 Netty是什么 大概用Netty的,無(wú)論新手還是老手,都知道它是一個(gè)網(wǎng)絡(luò)通訊框架。所謂框架,基本上都是一個(gè)作用:基于底層API,提供更便捷的編程模型。那么通訊框架到底做了什么事情呢?回答這個(gè)問(wèn)題并不太容易,我們...

    _Suqin 評(píng)論0 收藏0
  • Netty3文檔翻譯(二)

    摘要:豐富的緩存數(shù)據(jù)結(jié)構(gòu)使用它自己的緩存來(lái)表示字節(jié)序列而不是的。針對(duì)有一個(gè)定義良好的事件模型。有一些協(xié)議是多層的建立在其他低級(jí)協(xié)議基礎(chǔ)上。此外,甚至不是完全線程安全的。協(xié)議由標(biāo)準(zhǔn)化為。協(xié)議緩存整合是一個(gè)高效二進(jìn)制協(xié)議的快速實(shí)現(xiàn)。 Chapter 2、結(jié)構(gòu)概覽 這一節(jié)我們將確認(rèn)Netty提供的核心功能是什么,以及它們?cè)趺礃?gòu)成一個(gè)完整的網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)堆棧。 1、豐富的緩存數(shù)據(jù)結(jié)構(gòu) Netty使用它...

    Zhuxy 評(píng)論0 收藏0
  • 關(guān)于拷貝的一點(diǎn)認(rèn)識(shí)

    摘要:前言從字面意思理解就是數(shù)據(jù)不需要來(lái)回的拷貝,大大提升了系統(tǒng)的性能這個(gè)詞我們也經(jīng)常在,,,等框架中聽(tīng)到,經(jīng)常作為其提升性能的一大亮點(diǎn)下面從的幾個(gè)概念開(kāi)始,進(jìn)而在分析零拷貝。 前言 從字面意思理解就是數(shù)據(jù)不需要來(lái)回的拷貝,大大提升了系統(tǒng)的性能;這個(gè)詞我們也經(jīng)常在java nio,netty,kafka,RocketMQ等框架中聽(tīng)到,經(jīng)常作為其提升性能的一大亮點(diǎn);下面從I/O的幾個(gè)概念開(kāi)始,...

    荊兆峰 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<