ftp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;

namespace FtpClient
{
    public class FtpFileDownloadService
    {
        #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 _SaveFileExtName;//保存文件扩展名
        private int _TaskNum;//任务数量        
        private volatile int _DownloadSize;//当前下载大小
        private Task[] _TaskList;//任务数组
        private List<string> _TempFiles = new List<string>();
        private FtpWebRequest ftpRequest;

        #endregion

        #region 属性
        /// <summary>
        /// 服务器地址
        /// </summary>
        public string Server
        {
            get { return _Server; }
            set { _Server = value; }
        }
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get { return _UserName; }
            set { _UserName = value; }
        }
        /// <summary>
        /// 密码
        /// </summary>
        public string Password
        {
            get { return _Password; }
            set { _Password = value; }
        }
        /// <summary>
        /// 端口
        /// </summary>
        public int Port
        {
            get { return _Port; }
            set { _Port = value; }
        }
        /// <summary>
        /// 文件大小
        /// </summary>
        public long FileSize
        {
            get { return _FileSize; }
            set { _FileSize = value; }
        }
        /// <summary>
        /// 文件地址
        /// </summary>
        public string FileUrl
        {
            get { return _FileUrl; }
            set { _FileUrl = value; }
        }
        /// <summary>
        /// 保存路经 
        /// </summary>
        public string SavePath
        {
            get { return _SavePath; }
            set { _SavePath = value; }
        }
        /// <summary>
        /// 保存文件名
        /// </summary>
        public string SaveFileName
        {
            get { return _SaveFileName; }
            set { _SaveFileName = value; }
        }
        /// <summary>
        /// 保存文件扩展名
        /// </summary>
        public string SaveFileExtName
        {
            get { return _SaveFileExtName; }
            set { _SaveFileExtName = value; }
        }
        /// <summary>
        /// 任务数量
        /// </summary>
        public int TaskNum
        {
            get { return _TaskNum; }
            set { _TaskNum = value; }
        }

        public int DownloadSize
        {
            get { return _DownloadSize; }
        }
        /// <summary>
        /// 服务器请求地址
        /// </summary>
        public string RequestPath
        {
            get { return string.Format("ftp://{0}:{1}//{2}", _Server, _Port, _FileUrl); }
        }

        public string SaveFullFileName
        {
            get { return Path.Combine(_SavePath, _SaveFileName + _SaveFileExtName); }
        }

        #endregion

        #region Constructor    

        public FtpFileDownloadService(string server, string username, string password, string fileUrl, string savePath)
        : this(server, username, password, 5, fileUrl, savePath)
        {
        }

        public FtpFileDownloadService(string server, string username, string password, int taskNum, string fileUrl, string savePath)
        : this(server, username, password, 21, taskNum, fileUrl, savePath, "", "")
        {
            var fi = new FileInfo(fileUrl.Replace("//", "\"));
            _SaveFileName = fi.Name.Substring(0, fi.Name.IndexOf('.'));
            _SaveFileExtName = fi.Extension;
        }

        public FtpFileDownloadService(string server, string username, string password, int port, int taskNum, string fileUrl, string savePath, string saveFileName, string saveFileExtName)
        {
            _TaskList = new Task[taskNum];
            _Server = server;
            _UserName = username;
            _Password = password;
            _Port = port;
            _TaskNum = taskNum;
            _FileUrl = fileUrl;
            _SavePath = savePath;
            _SaveFileName = saveFileName;
            _SaveFileExtName = saveFileExtName;
        }

        #endregion

        #region Functions

        public async Task Download()
        {
            FtpWebResponse response = null;
            Stream ftpStream = null;
            try
            {
                if (!Directory.Exists(_SavePath)) Directory.CreateDirectory(_SavePath);
                _FileSize = GetFileSize();
                int singelNum = (int)(_FileSize / _TaskNum);//平均分配
                int remainder = (int)(_FileSize % _TaskNum);//获取剩余的

                FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(RequestPath));
                ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
                ftpRequest.KeepAlive = false;
                ftpRequest.UseBinary = true;
                ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
                response = (FtpWebResponse)ftpRequest.GetResponse();
                ftpStream = response.GetResponseStream();

                for (int i = 0; i < _TaskNum; i++)
                {
                    int from = i * singelNum;
                    int to = i * singelNum + singelNum - 1;
                    if (remainder != 0 && (_TaskNum - 1) == i)//剩余的交给最后一个任务
                    {
                        to += remainder;
                    }
                    _TaskList[i] = Task.Run(() => { DownloadFile(ftpStream, from, to, "task" + i + 1); });
                }

                await Task.WhenAll(_TaskList);
                ftpStream.Close();
                response.Close();
                Complete();
            }
            catch (Exception ex)
            {
                ftpStream.Close();
                response.Close();
                throw ex;
            }

        }

        /// <summary>
        /// 拆分分段下载
        /// </summary>       
        private void DownloadFile(Stream stream, int from, int to, string id)
        {
            string tmpFileBlock = string.Format(@"{0}{1}_{2}.dat", _SavePath, _SaveFileName, id);           
            _TempFiles.Add(tmpFileBlock);           
            int readCount = 0;
            int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            using (FileStream outputStream = new FileStream(tmpFileBlock, FileMode.Create))
            {
                while ((readCount = stream.Read(buffer, 0, bufferSize)) > 0)
                {
                    if (from + readCount < to)
                    {
                        outputStream.Write(buffer, 0, readCount);
                        from = from + readCount;
                    }
                    else
                    {
                        outputStream.Write(buffer, 0, to - from);
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 合并临时文件
        /// </summary>
        private void Complete()
        {
            Stream mergeFile = new FileStream(SaveFullFileName, 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();          
        }

        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <returns></returns>
        private long GetFileSize()
        {
            FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(RequestPath));
            ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
            ftpRequest.KeepAlive = false;
            ftpRequest.UseBinary = true;
            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
            return response.ContentLength;
        }

        #endregion

    }
}

原文地址:https://www.cnblogs.com/lenther2002/p/6876291.html