FTP上传下载 FTP操作类 FTPHelper 异步上传 递归创建文件文件夹


    public class FtpState
    {
        private ManualResetEvent wait;
        private FtpWebRequest request;
        private string fileName;
        private Exception operationException = null;
        string status;

        public FtpState()
        {
            wait = new ManualResetEvent(false);
        }

        public ManualResetEvent OperationComplete
        {
            get { return wait; }
        }

        public FtpWebRequest Request
        {
            get { return request; }
            set { request = value; }
        }

        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }
        public Exception OperationException
        {
            get { return operationException; }
            set { operationException = value; }
        }
        public string StatusDescription
        {
            get { return status; }
            set { status = value; }
        }
    }

    class FTPHelper
    {
        string ftpUserID, ftpPassword;
        FtpWebRequest reqFTP;
        string _ftpRoot;
        string ftpRoot
        {
            get
            {
                if (!_ftpRoot.EndsWith("/")) _ftpRoot += "/";
                return _ftpRoot;
            }
            set
            {
                _ftpRoot = value;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="ftpRoot">如:(ftp://120.197.84.46:3796/ftproot/)</param>
        /// <param name="ftpUserID"></param>
        /// <param name="ftpPassword"></param>
        public FTPHelper(string ftpRoot, string ftpUserID, string ftpPassword)
        {
            this.ftpRoot = ftpRoot;
            this.ftpUserID = ftpUserID;
            this.ftpPassword = ftpPassword;
        }

        /// <summary>
        /// 连接ftp
        /// </summary>
        /// <param name="path"></param>
        public void Connect(string path)//连接ftp
        {
        //    if (reqFTP != null) return;
            // 根据uri创建FtpWebRequest对象
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));
            // 指定数据传输类型
            reqFTP.UseBinary = true;
            // ftp用户名和密码
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        }

        /// <summary>
        /// 从ftp服务器上获得文件列表
        /// </summary>
        /// <param name="path"></param>
        /// <param name="WRMethods"></param>
        /// <returns></returns>
        public string[] GetFileList(string path, string WRMethods)
        {
            string[] downloadFiles;
            StringBuilder result = new StringBuilder();
            try
            {
                Connect(path);

                reqFTP.Method = WRMethods;

                WebResponse response = reqFTP.GetResponse();

                StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名

                string line = reader.ReadLine();

                while (line != null)
                {
                    result.Append(line);
                    result.Append("\n");
                    line = reader.ReadLine();
                }

                // to remove the trailing '\n'

                result.Remove(result.ToString().LastIndexOf('\n'), 1);

                reader.Close();

                response.Close();

                return result.ToString().Split('\n');

            }

            catch (Exception ex)
            {
                Sxmobi.LogHelper.Error(this.GetType().ToString(), ex.Message, ex);
                downloadFiles = null;
                return downloadFiles;
            }
        }

        /// <summary>
        /// 从ftp服务器上获得文件列表
        /// </summary>
        /// <param name="path">指定目录</param>
        /// <returns></returns>
        public string[] GetFileList(string path)
        {
            return GetFileList(formatUrl( ftpRoot , path), WebRequestMethods.Ftp.ListDirectory);
        }

        /// <summary>
        /// 从ftp服务器上获得文件列表
        /// </summary>
        /// <returns></returns>
        public string[] GetFileList()
        {
            return GetFileList(ftpRoot, WebRequestMethods.Ftp.ListDirectory);
        }

        /// <summary>
        /// 从ftp服务器下载文件
        /// </summary>
        /// <param name="srcFilePath"></param>
        /// <param name="srcFilePath"></param>
        /// <param name="errorinfo"></param>
        /// <param name="saveName"></param>
        /// <returns></returns>
        public bool Download(string srcFilePath, string desFilePath,ref string errorinfo)
        {
            try
            {
                //if (File.Exists(desFilePath))
                //{
                //    errorinfo = string.Format("本地文件{0}已存在,无法下载", desFilePath);
                //    Sxmobi.LogHelper.Error(this.GetType().ToString(), errorinfo, null);
 
                //}
                string url = formatUrl(ftpRoot ,srcFilePath);
                Connect(url);//连接 
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                Sxmobi.FileHelper.EnsureDir(Path.GetDirectoryName(desFilePath));

                FileStream outputStream = new FileStream(desFilePath, FileMode.Create);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();

                errorinfo = "";

                return true;

            }

            catch (Exception ex)
            {
                errorinfo = string.Format("因{0},无法下载", ex.Message);
                Sxmobi.LogHelper.Error(this.GetType().ToString(), errorinfo, ex);
                return false;

            }

        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="dFile">目标文件(不带FTP根目录)</param>
        /// <param name="sFile">源文件</param>
        public void upLoad(string destFile, string srcFile)
        {
            upLoad(destFile, srcFile, false);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="dFile">目标文件(不带FTP根目录)</param>
        /// <param name="sFile">源文件</param>
        /// <param name="delSrcFile">上传完毕后是否删除源文件</param>
        public void upLoad(string destFile, string srcFile, bool delSrcFile)
        {
            try
            {
                string url = formatUrl(ftpRoot, destFile);
                // Create a Uri instance with the specified URI string.
                // If the URI is not correctly formed, the Uri constructor
                // will throw an exception.
                ManualResetEvent waitObject;

                Uri target = new Uri(url);

                string fileName = srcFile;
                FtpState state = new FtpState();

                //创建文件夹
    createFtpDir(url);

                //上传文件
                Connect(url);
                reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
                state.Request = reqFTP;
                state.FileName = fileName;

                // Get the event to wait on.
                waitObject = state.OperationComplete;
                reqFTP.BeginGetRequestStream(
                    new AsyncCallback(EndGetStreamCallback),
                    state
                );
                waitObject.WaitOne();

                if(delSrcFile)
                    File.Delete(state.FileName);

                if (state.OperationException != null)
                {
                    throw state.OperationException;
                }

            }
            catch (Exception ex)
            {
                Sxmobi.LogHelper.Error("upLoad", ex.Message, ex);
            }
        }
        /// <summary>
        /// 递归创建文件夹
        /// </summary>
        /// <param name="path"></param>
        void createFtpDir(string path)
        {
            if (path.Length <= ftpRoot.Length) return;
            int pos = path.LastIndexOf("/");
            path = path.Substring(0, pos);
            string[] dirs = GetFileList(Path.GetDirectoryName(path));
            if (dirs == null || dirs.Length == 0)
            {
                createFtpDir(path);
                try
                {
                    Connect(path);//连接 
                    reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
                    reqFTP.UseBinary = true;
                    FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                    Stream ftpStream = response.GetResponseStream();
                    ftpStream.Close();
                    response.Close();
                }
                catch { }
            }

            return;

        }

        private void EndGetStreamCallback(IAsyncResult ar)
        {
            FtpState state = (FtpState)ar.AsyncState;

            Stream requestStream = null;
            // End the asynchronous call to get the request stream.
            try
            {
                requestStream = state.Request.EndGetRequestStream(ar);
                // Copy the file contents to the request stream.
                const int bufferLength = 2048;
                byte[] buffer = new byte[bufferLength];
                int count = 0;
                int readBytes = 0;
                FileStream stream = File.OpenRead(state.FileName);
                do
                {
                    readBytes = stream.Read(buffer, 0, bufferLength);
                    requestStream.Write(buffer, 0, readBytes);
                    count += readBytes;
                }
                while (readBytes != 0);
                stream.Close();
                stream.Dispose();
                //  Console.WriteLine("Writing {0} bytes to the stream.", count);
                // IMPORTANT: Close the request stream before sending the request.
                requestStream.Close();
                // Asynchronously get the response to the upload request.
                state.Request.BeginGetResponse(
                    new AsyncCallback(EndGetResponseCallback),
                    state
                );
            }
            // Return exceptions to the main application thread.
            catch (Exception e)
            {
                // Console.WriteLine("Could not get the request stream.");
                Sxmobi.LogHelper.Error("EndGetStreamCallback", "Could not get the request stream.", e);
                state.OperationException = e;
                state.OperationComplete.Set();
                return;
            }

        }

        // The EndGetResponseCallback method 
        // completes a call to BeginGetResponse.
        private void EndGetResponseCallback(IAsyncResult ar)
        {
            FtpState state = (FtpState)ar.AsyncState;
            FtpWebResponse response = null;
            try
            {
                response = (FtpWebResponse)state.Request.EndGetResponse(ar);
                response.Close();
                state.StatusDescription = response.StatusDescription;
                // Signal the main application thread that
                // the operation is complete.
                state.OperationComplete.Set();
            }
            // Return exceptions to the main application thread.
            catch (Exception e)
            {
                Sxmobi.LogHelper.Error("EndGetResponseCallback", "Error getting response.", e);
                state.OperationException = e;
                state.OperationComplete.Set();
            }
        }


 

        /// <summary>
        /// 地址加入前缀
        /// </summary>
        /// <param name="host">服务器前缀(如:"ftp://www.xxx.com"、"http://www.xxx.com/a.htm")</param>
        /// <param name="src"></param>
        /// <returns></returns>
        public static string formatUrl(string host, string src)
        {
            int l = host.LastIndexOf("/");
            if (l > 10)
                host = host.Substring(0, l);

            src = src.Replace("\\", "/");

            if (src.ToLower().IndexOf("http") < 0 && src.ToLower().IndexOf("ftp") < 0)//拼凑地址
            {
                if (!src.StartsWith("/")) src = "/" + src;
                src = host + src;
            }

            return src;
        }

    }

原文地址:https://www.cnblogs.com/dashi/p/4034725.html