1. 程式人生 > >基於netty4的檔案下載

基於netty4的檔案下載

在使用過程中發現這種方式下載檔案,是在將檔案載入至記憶體後再往服務端傳送,會隨之檔案的大小而佔用記憶體。我測試中下載2G的檔案,發現記憶體升高,下載10G檔案時無法下載。

客戶端:

  1. publicclass DownLoadClient {  
  2.     private StringBuffer resultBuffer = new StringBuffer();  
  3.     private EventLoopGroup group = null;  
  4.     private HttpDataFactory factory = null;  
  5.     private ChannelFuture future = 
    null;  
  6.     private Object waitObject = new Object();  
  7.     private String downFileName = null;  
  8.     public DownLoadClient(String host, int port) throws Exception {  
  9.         this.group = new NioEventLoopGroup();  
  10.         this.factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE);  
  11.         Bootstrap b = new
     Bootstrap();  
  12.         b.option(ChannelOption.TCP_NODELAY, true);  
  13.         b.option(ChannelOption.SO_RCVBUF, 1048576*200);  
  14.         b.option(ChannelOption.SO_KEEPALIVE, true);  
  15.         b.group(group).channel(NioSocketChannel.class);  
  16.         b.handler(new DownLoadClientIntializer());  
  17.         this.future = b.connect(host, port).sync();  
  18.     }  
  19.     publicvoid downLoadFile(String fileName) {  
  20.         if(fileName == null || "".equals(fileName) || fileName.indexOf(".") == -1) {  
  21.             System.out.println("下載的檔名未正確指定...");  
  22.             return;  
  23.         }  
  24.         this.downFileName = fileName;  
  25.         try {  
  26.             HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, fileName);  
  27.             Channel channel = this.future.channel();  
  28.             if(channel.isActive() && channel.isWritable()) {  
  29.                 channel.writeAndFlush(request);  
  30.             }  
  31.             channel.closeFuture().sync();  
  32.         } catch (Exception e) {  
  33.             e.printStackTrace();  
  34.         }  
  35.     }  
  36.     publicvoid shutdownClient() {  
  37.         // 等待資料的傳輸通道關閉
  38.         group.shutdownGracefully();  
  39.         factory.cleanAllHttpDatas();  
  40.     }  
  41.     publicboolean isCompleted() {  
  42.         while(waitObject != null) {  
  43.             //當通道處於開通和活動時,處於等待
  44.         }  
  45.         if(resultBuffer.length() > 0) {  
  46.             if("200".equals(resultBuffer.toString())) {  
  47.                 resultBuffer.setLength(0);  
  48.                 returntrue;  
  49.             }  
  50.         }  
  51.         returnfalse;  
  52.     }  
  53.     privateclass DownLoadClientIntializer extends ChannelInitializer<SocketChannel> {  
  54.         @Override
  55.         protectedvoid initChannel(SocketChannel ch) throws Exception {  
  56.             ChannelPipeline pipeline = ch.pipeline();  
  57.             pipeline.addLast("decoder"new HttpResponseDecoder());  
  58.             pipeline.addLast("encoder"new HttpRequestEncoder());    
  59.             pipeline.addLast("chunkedWriter"new ChunkedWriteHandler());    
  60.             pipeline.addLast("dispatcher"new DownLoadClientHandler());  
  61.         }  
  62.     }  
  63.     privateclass DownLoadClientHandler extends SimpleChannelInboundHandler<HttpObject> {  
  64.         privateboolean readingChunks = false;  
  65.         private File downloadFile = null;  
  66.         private FileOutputStream fOutputStream = null;  
  67.         privateint succCode = 200;  
  68.         protectedvoid channelRead0(ChannelHandlerContext ctx, HttpObject msg)  
  69.                 throws Exception {  
  70.             if (msg instanceof HttpResponse) {  
  71.                 HttpResponse response = (HttpResponse) msg;  
  72.                 succCode = response.getStatus().code();  
  73.                 if (succCode == 200) {  
  74.                     setDownLoadFile();  
  75.                     readingChunks = true;  
  76.                 }  
  77.             }  
  78.             if (msg instanceof HttpContent) {  
  79.                 HttpContent chunk = (HttpContent) msg;  
  80.                 if (chunk instanceof LastHttpContent) {  
  81.                     readingChunks = false;  
  82.                 }   
  83.                 ByteBuf buffer = chunk.content();  
  84.                 byte[] dst = newbyte[buffer.readableBytes()];  
  85.                 if(succCode == 200) {  
  86.                     while(buffer.isReadable()) {  
  87.                         buffer.readBytes(dst);  
  88.                         fOutputStream.write(dst);  
  89.                     }  
  90.                     if (null != fOutputStream) {  
  91.                         fOutputStream.flush();  
  92.                     }  
  93.                 }  
  94.             }  
  95.             if (!readingChunks) {  
  96.                 if (null != fOutputStream) {  
  97.                     fOutputStream.flush();  
  98.                     fOutputStream.close();  
  99.                     downloadFile = null;  
  100. 相關推薦

    基於netty4檔案下載

    在使用過程中發現這種方式下載檔案,是在將檔案載入至記憶體後再往服務端傳送,會隨之檔案的大小而佔用記憶體。我測試中下載2G的檔案,發現記憶體升高,下載10G檔案時無法下載。客戶端:publicclass DownLoadClient {      private StringB

    【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案下載(二)

    上篇中我們介紹了基於MVP的Retrofit2+RXjava封裝,還沒有看的點選這裡,這一篇我們來說說檔案下載的實現。 首先,我們先在ApiServer定義好呼叫的介面 @GET Observable<ResponseBody> downloadFile(@

    [原始碼和文件分享]基於WinInet的HTTPS檔案下載實現

    背景 如果你之前寫過基於WinInet庫的HTTP下載檔案,那麼你在看完本文之後,就會發覺,這是和HTTP檔案下載的程式碼幾乎是一模一樣的,就是有幾個地方的區別而已。但是,本文不是對HTTP和HTTPS在WinInet庫中的區別進行總結的,總結就另外寫。 本文就是基於WinInet網路庫,實

    [原始碼和文件分享]基於WinInet實現的HTTP檔案下載

    背景 之前寫過的網路資料傳輸的小程式都是基於Socket去寫的,所以,如果要用Socket傳輸資料到網站,還需要根據域名獲取伺服器的IP地址,然後再建立連線,傳輸資料。雖然,Socket也可以實現網路傳輸,但是,總感覺不是很方便。所以,後來隨著知識面的拓展,瞭解到Windows還專門提供了Win

    基於xutils3的單檔案下載

    開篇都不知道要叨叨啥,唉~,直接進入正題——>go!! 介面就是一個button,就不貼了。 MainActivity  package com.fun.downloaduploaddemo; import android.os.Bundle; import android.

    【Netty基礎】基於HTTP的檔案下載Server例項

    功能描述:開啟瀏覽器,可實現檔案下載功能 例: public class HttpDownLoadFileServer { private static final String DEFAULT_URL = "/src/image/";

    Python基於django提供大檔案下載介面及Python基於tornado下載檔案

    Django下載大檔案介面 程式碼 我是基於django的rest介面外掛提供的下載檔案介面,除了需要安裝django之外還需要安裝djangorestframework庫 不多說,下面直接貼程式碼 #views.py from rest_fr

    基於HTTP的多執行緒檔案下載功能實現

    思想 檔案資訊獲取的獲取方式與單執行緒的方式一樣 與單執行緒相比不同的是將遠端檔案分塊併發獲取,然後再併發寫入到本地暫存檔案中 遠端檔案分塊的實現依據是:connection.setRequestProperty(“Range”,”bytes=”+start

    基於HTTP的單執行緒檔案下載功能實現

    思路 使用http請求遠端檔案地址 從響應體中獲取檔案頭資訊 讀取響應體中的輸入流,並寫入本地檔案輸出流中 程式碼實現 package org.hanmeis; import java.io.FileOutputStream; import

    Android基於Okhttp3的檔案下載工具類

    需求中有需要簡易的下載檔案的,例如圖片,音訊,視訊等。首先這個下載工具類沒有斷點下載,也就是說沒有暫停,快取。不過解決日常工作中的小檔案下載是綽綽有餘的。下面可以看一看 一、新增okhttp3的遠端依賴 compile 'com.squareup.okhttp3:ok

    java web 基於IO流的檔案下載示例

    下載檔案有時候直接就是一個a連結,連結檔案地址,很ok,很簡單,但是這樣有些弊病,比如說,我要是想統計檔案下載數量呢,再加上,檔案並不是都放在伺服器目錄下,也有可能是別的目錄,再或者,像 .txt 的直接a連結就打開了。所以使用程式來下載也是很有必要的。 show code

    C++ 基於libcurl的html 檔案下載

    lincurl的環境配置,在這裡不做詳細描述,程式碼實現程式如下: #include <stdio.h> #include <curl/curl.h> /***********************************************

    基於RandomAccessFile實現斷點檔案下載功能

    RandomAccessFile是用來訪問那些儲存資料記錄的檔案的,你就可以用seek( )方法來訪問記錄,並進行讀寫了。這些記錄的大小不必相同;但是其大小和位置必須是可知的。但是該類僅限於操作檔案。RandomAccessFile不屬於InputStream和Output

    專案常見功能(1) 下載 批量下載檔案下載 下載進度條

    最通用的就是讀取伺服器上檔案,response 設定響應頭讓瀏覽器知道這是要下載的,然後response相應即可 1、ajax 響應內容只能是字串,不能是流所以  不能傳送請求下載檔案,要使用window.location.href= url  或者 <a href="

    MATLAB R2016a 64位安裝包及破解檔案下載

    【MATLAB簡介】 MATLAB是矩陣實驗室(Matrix Laboratory)的簡稱,是美國MathWorks公司出品的商業數學軟體,用於演算法開發、資料視覺化、資料分析以及數值計算的高階技術計算語言和互動式環境。 MATLAB和Mathematica、Maple並稱為三大數學軟體。它

    easyPoi處理檔案下載檔名為空問題----請求頭資訊

    導包:同上一篇匯出封裝請求引數 定義註解: import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import java.lang.annotation.*; /** * 匯出Excel註解. */ @Document

    Struts的檔案下載功能

    Action層: public String myDownloadFile() { HttpServletResponse response = ServletActionContext.getResponse(); String myFileName = getFilename()

    Spring 實現檔案下載功能

    方式1: public void download(HttpServletResponse response,@RequestParam(value="params") String params) throws IOException, DocumentException{ response

    VB.net 檔案下載示例

    Imports System.IO Imports System.Net   Public Class Form1     Private Sub btnDown_Click(sender As Object, e As EventArgs) Handles btnDo

    php 檔案下載

    <?php $document=$db->getRow("SELECT file_name,file_url FROM documents WHERE id='".$_REQUEST['id']."'"); $fileUrl = $document['file_u