多线程下载(FtpWebRequest)

网上没找到FtpWebRequest多线程下载的资料,自己写了一个。但没达到预期效果,下面是测试结果:

//1线程下载133M 18秒
//5线程 下载133M 40秒

//单线程 下载133M 12秒

期望高手不吝赐教,下面是完整代码

首先命名空间

 

using  System.Collections.Generic;
using  System.IO;
using  System.Threading;
using  System.Net;

 

 

类主体:

 

ExpandedBlockStart.gif 代码
     public   class  MultiFtpService
    {
        
#region  变量

        
private   string  _Server; // 服务器地址
         private   string  _UserName; // 用户名
         private   string  _Password; // 密码
         private   int  _Port; // 端口
         private   long  _FileSize; // 文件大小
         private   string  _FileUrl; // 文件地址
         private   string  _SavePath; // 保存路经        
         private   string  _SaveFileName; // 保存文件名
         private   string  _SaveExtName; // 保存文件扩展名
         private   int  _ThreadNum; // 线程数量
         private   short  _ThreadCompleteNum; // 线程完成数量
         private   bool  _IsComplete  =   false ; // 是否完成
         private   volatile   int  _DownloadSize; // 当前下载大小
         private  Thread[] _Thread; // 线程数组
         private  List < string >  _TempFiles  =   new  List < string > ();
        
private  FtpWebRequest ftpRequest;

        
#endregion

        
#region  属性

        
public   string  Server
        {
            
get  {  return  _Server; }
            
set  { _Server  =  value; }
        }

        
public   string  UserName
        {
            
get  {  return  _UserName; }
            
set  { _UserName  =  value; }
        }

        
public   string  Password
        {
            
get  {  return  _Password; }
            
set  { _Password  =  value; }
        }

        
public   int  Port
        {
            
get  {  return  _Port; }
            
set  { _Port  =  value; }
        }

        
public   long  FileSize
        {
            
get  {  return  _FileSize; }
            
set  { _FileSize  =  value; }
        }

        
public   string  FileUrl
        {
            
get  {  return  _FileUrl; }
            
set  { _FileUrl  =  value; }
        }

        
public   string  SavePath
        {
            
get  {  return  _SavePath; }
            
set  { _SavePath  =  value; }
        }

        
public   string  SaveFileName
        {
            
get  {  return  _SaveFileName; }
            
set  { _SaveFileName  =  value; }
        }

        
public   string  SaveExtName
        {
            
get  {  return  _SaveExtName; }
            
set  { _SaveExtName  =  value; }
        }

        
public   int  ThreadNum
        {
            
get  {  return  _ThreadNum; }
            
set  { _ThreadNum  =  value; }
        }

        
public   short  ThreadCompleteNum
        {
            
get  {  return  _ThreadCompleteNum; }
            
set  { _ThreadCompleteNum  =  value; }
        }

        
public   bool  IsComplete
        {
            
get  {  return  _IsComplete; }
        }

        
public   int  DownloadSize
        {
            
get  {  return  _DownloadSize; }
        }

        
#endregion

        
#region  Constructor

        
public  MultiFtpService( string  server,  string  username,  string  password,  int  threadNum)
            : 
this (server, username, password,  21 , threadNum,  "" "" )
        {
        }

        
public  MultiFtpService( string  server,  string  username,  string  password,  int  port, int  threadNum)
            : 
this (server, username, password, port, threadNum,  "" "" )
        {
        }

        
public  MultiFtpService( string  server,  string  username,  string  password,  int  threadNum,  string  fileUrl,  string  savePath)
            : 
this (server, username, password,  21 , threadNum, fileUrl, savePath)
        {
        }

        
public  MultiFtpService( string  server,  string  username,  string  password,  int  port, int  threadNum,  string  fileUrl,  string  savePath)
        {
            _Server 
=  server;
            _UserName 
=  username;
            _Password 
=  password;
            _Port 
=  port;
            _ThreadNum 
=  threadNum;
            _FileUrl 
=  fileUrl;
            _SavePath 
=  savePath;
            _Thread 
=   new  Thread[_ThreadNum];
        }

        
#endregion

        
#region  Functions

        
public   void  Start()
        {
            FtpWebRequest ftpRequest 
=  (FtpWebRequest)FtpWebRequest.Create( new  Uri( " ftp:// "   +  _Server  +   " : "   +  _Port  +   " / "   +  _FileUrl));
            ftpRequest.Method 
=  WebRequestMethods.Ftp.GetFileSize;
            ftpRequest.KeepAlive 
=   false ;
            ftpRequest.UseBinary 
=   true ;
            ftpRequest.Credentials 
=   new  NetworkCredential(_UserName, _Password);
            FtpWebResponse response 
=  (FtpWebResponse)ftpRequest.GetResponse();
            _FileSize 
=  response.ContentLength;
            
int  singelNum  =  ( int )(_FileSize  /  _ThreadNum); // 平均分配
             int  remainder  =  ( int )(_FileSize  %  _ThreadNum); // 获取剩余的
             for  ( int  i  =   0 ; i  <  _ThreadNum; i ++ )
            {
                List
< int >  range  =   new  List < int > ();
                range.Add(i 
*  singelNum);
                
if  (remainder  !=   0   &&  (_ThreadNum  -   1 ==  i) // 剩余的交给最后一个线程
                    range.Add(i  *  singelNum  +  singelNum  +  remainder  -   1 );
                
else
                    range.Add(i 
*  singelNum  +  singelNum  -   1 );
                _Thread[i] 
=   new  Thread(()  =>  { Download(range[ 0 ], range[ 1 ]); });
                _Thread[i].Name 
=   string .Format( " thread_{0} " ,i  +   1 );
                _Thread[i].Start();
            }
        }

        
///   <summary>
        
///  拆分分段下载
        
///   </summary>
        
///   <param name="from"> 开始 </param>
        
///   <param name="to"> 结束 </param>
         private   void  Download( int  from,  int  to)
        {
            
string  tmpFileBlock  =   string .Format( @" {0}\{1}_{2}.dat " , _SavePath, _SaveFileName, Thread.CurrentThread.Name);
            _TempFiles.Add(tmpFileBlock);
            
int  count  =   0 ;
            
int  readCount  =   0 ;
            
try
            {
                ftpRequest 
=  (FtpWebRequest)FtpWebRequest.Create( new  Uri( " ftp:// "   +  _Server  +   " : "   +  _Port  +   " / "   +  _FileUrl));
                
// ftpRequest.ContentOffset = from; // 设置文件的偏移量
                ftpRequest.Method  =  WebRequestMethods.Ftp.DownloadFile;
                ftpRequest.UseBinary 
=   true ;
                ftpRequest.Credentials 
=   new  NetworkCredential(UserName, Password);
                
using  (FileStream outputStream  =   new  FileStream(tmpFileBlock, FileMode.Create))
                
using  (FtpWebResponse response  =  (FtpWebResponse)ftpRequest.GetResponse())
                
using  (Stream ftpStream  =  response.GetResponseStream())
                {
                    
int  bufferSize  =   81920 ;
                    
byte [] buffer  =   new   byte [bufferSize];

                    
while  ((readCount  =  ftpStream.Read(buffer,  0 , bufferSize))  >   0 )
                    {
                        count 
+=  readCount;
                        
if  (from < to  &&  from  +  readCount  >=  to)
                        {
                            outputStream.Write(buffer, 
0 , to - from);
                            _DownloadSize 
+=  to  -  from;
                            
break ;
                        }
                        
else   if  (from  ==  count  -  readCount)
                        {
                            outputStream.Write(buffer, 
0 , readCount);
                            _DownloadSize 
+=  readCount;
                            from 
=  count;
                        }
                        
else   if  (count  >  from  &&  from  >  count  -  readCount)
                        {
                            outputStream.Write(buffer, readCount 
-  (count  -  from), count  -  from);
                            _DownloadSize 
+=  count  -  from;
                            from 
=  count;
                        }
                    }
                    _ThreadCompleteNum
++ ;
                }
            }
            
catch  (Exception e)
            {
                
throw  e;
            }
            
if  (_ThreadCompleteNum  ==  _ThreadNum)
            {
                Complete();
            }
        }

        
///   <summary>
        
///  合并临时文件
        
///   </summary>
         private   void  Complete()
        {
            Stream mergeFile 
=   new  FileStream( string .Format( @" {0}\{1}{2} " ,_SavePath,_SaveFileName,_SaveExtName), FileMode.Create);
            BinaryWriter AddWriter 
=   new  BinaryWriter(mergeFile);
            
foreach  ( string  file  in  _TempFiles)
            {
                
using  (FileStream fs  =   new  FileStream(file, FileMode.Open))
                
using (BinaryReader tempReader  =   new  BinaryReader(fs))
                {
                    AddWriter.Write(tempReader.ReadBytes((
int )fs.Length));
                }
                File.Delete(file);
            }
            AddWriter.Close();
            _IsComplete 
=   true ;
        }

        
#endregion
    }

 

 

测试代码:

 

ExpandedBlockStart.gif 代码
MultiFtpService multiFtp  =   new  MultiFtpService( " 172.18.118.106 " " ff " " ff " , 1 );
string  path  =   " 10031544820/20100310/4014200 " ;
            DateTime dt 
=  DateTime.Now;
            
string  fileName  =   " CX.IMG " ;
            
// ftp.Download(path + "/" + fileName, pathdir + "/" + path + "/" + fileName, true);
            multiFtp.FileUrl  =  path  +   " / "   +  fileName;
            multiFtp.SavePath 
=  pathdir  +   " / "   +  path;
            multiFtp.SaveFileName 
=  fileName.Substring( 0 , fileName.IndexOf( ' . ' ));
            multiFtp.SaveExtName 
=  fileName.Substring(fileName.IndexOf( ' . ' ));
            multiFtp.Start();
            
while  ( ! multiFtp.IsComplete)
            {
                System.Threading.Thread.Sleep(
1 );
            }
            MessageBox.Show(
" 完成:前时间为 "   +  dt.ToString( " yyyy-MM-dd hh:mm:ss " +   " \n "   +   " 现在时间为 "   +  DateTime.Now.ToString( " yyyy-MM-dd hh:mm:ss " ));

 

 

转载于:https://www.cnblogs.com/nyzfl/archive/2010/04/21/1717461.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值