C# Ftp异步文件上传

using System;
using System.IO;
using System.Net;
using System.Threading;

namespace FinanceCenter.Services.Tools
{
    public class FtpHelper
    {
        public class FtpState
        {
            private ManualResetEvent wait;
            private FtpWebRequest request;
            private string fullName;
            private Exception operationException;
            string statusCode;
            string statusDescription;
            string userName;
            string password;
            string ftpServerIP;
            string fileName;
            public Exception OperationException
            {
                get
                {
                    return operationException;
                }

                set
                {
                    operationException = value;
                }
            }
            public ManualResetEvent OperationComplete
            {
                get { return wait; }
            }
            public FtpWebRequest Request
            {
                get
                {
                    return request;
                }

                set
                {
                    request = value;
                }
            }

            public string FullName
            {
                get
                {
                    return fullName;
                }

                set
                {
                    fullName = value;
                }
            }

            public string StatusCode
            {
                get
                {
                    return statusCode;
                }

                set
                {
                    statusCode = value;
                }
            }

            public string StatusDescription
            {
                get
                {
                    return statusDescription;
                }

                set
                {
                    statusDescription = value;
                }
            }

            public string UserName
            {
                get
                {
                    return userName;
                }

                set
                {
                    userName = value;
                }
            }

            public string Password
            {
                get
                {
                    return password;
                }

                set
                {
                    password = value;
                }
            }

            public string FtpServerIP
            {
                get
                {
                    return ftpServerIP;
                }

                set
                {
                    ftpServerIP = value;
                }
            }

            public string FileName
            {
                get
                {
                    return fileName;
                }

                set
                {
                    fileName = value;
                }
            }

            public FtpState(string ftpServerIP, string userName, string password)
            {
                FtpServerIP = ftpServerIP;
                UserName = userName;
                Password = password;
                FileName = Path.GetFileName(fullName);
                wait = new ManualResetEvent(false);
            }


        }

        public static bool AsynchronousFtpUpLoader(string FullName, out string ftppath)
        {
            FtpState AsyncState = new FtpState(Common.Ftp_Url, Common.FtpAccount, Common.FtpPwd);
            AsyncState.FullName = FullName;
            ManualResetEvent waitObject;
            Uri target = new Uri(Common.Ftp_Url + Path.GetFileName(FullName));
            //FtpState AsyncState = new FtpState();
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
            request.Method = WebRequestMethods.Ftp.UploadFile;
            //这个例子使用匿名登录。
            //默认情况下,请求是匿名的; 证书不需要指定。
            //这个示例仅指定凭据
            //控制操作如何在服务器上登录。
            request.Credentials = new NetworkCredential(AsyncState.UserName, AsyncState.Password);
            //是否指定SSL 连接
            request.EnableSsl = false;
            //将请求存储在我们传入的对象中
            //异步操作。
            AsyncState.Request = request;
            AsyncState.FullName = AsyncState.FullName;
            //让事件继续等待。
            waitObject = AsyncState.OperationComplete;
            //异步获取文件内容的流。
            request.BeginGetRequestStream(
            new AsyncCallback(EndGetStreamCallback),
            AsyncState
            );
            //阻塞当前线程,直到所有操作完成为止。
            waitObject.WaitOne();
            //操作要么完成,要么抛出异常。
            if (AsyncState.OperationException != null)
            {
                ftppath = target.ToString();
                return false;
            }
            else
            {
                ftppath = target.ToString();
                return true;
            }

        }
        private static void EndGetStreamCallback(IAsyncResult ar)
        {
            FtpState AsyncState = (FtpState)ar.AsyncState;
            Stream requestStream;
            try
            {
                requestStream = AsyncState.Request.EndGetRequestStream(ar);
                const int bufferLength = 2048;
                byte[] _array = new byte[bufferLength];
                int count = 0;
                int readBytes = 0;
                FileStream fs = File.OpenRead(AsyncState.FullName);
                do
                {
                    readBytes = fs.Read(_array, 0, bufferLength);
                    requestStream.Write(_array, 0, readBytes);
                    count += count;
                } while (readBytes != 0);
                //将字节写入流
                Console.WriteLine("{0}-字节写入流");
                fs.Close();
                requestStream.Close();
                AsyncState.Request.BeginGetResponse(
                new AsyncCallback(EndGetResponseCallback),
                AsyncState
                );

            }
            catch (Exception e)
            {
                Console.WriteLine("错误响应:{0}", e.Message);
                AsyncState.OperationComplete.Set();
                AsyncState.OperationException = e;

            }
        }
        private static void EndGetResponseCallback(IAsyncResult ar)
        {
            FtpState AsyncState = (FtpState)ar.AsyncState;
            FtpWebResponse response;
            try
            {
                response = (FtpWebResponse)AsyncState.Request.EndGetResponse(ar);
                response.Close();
                AsyncState.StatusCode = response.StatusCode.ToString();
                AsyncState.StatusDescription = response.StatusDescription;
                AsyncState.OperationComplete.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine("错误响应:{0}", e.Message);
                AsyncState.OperationComplete.Set();
                AsyncState.OperationException = e;
            }
        }
        public static bool FtpUpload(string filepath, string filename)
        {
            try
            {
                FileInfo fi = new FileInfo(filepath);
                //定义上传目录
                string url = Common.Ftp_Url + filename;
                FtpWebRequest ftp;
                ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(url));
                //ftp账号密码
                ftp.Credentials = new NetworkCredential("test", "test");
                //如果是代理上网,不加这句话,就会报错误【使用 HTTP 代理时不支持请求的 FTP 命令。】
                ftp.Proxy = null;
                ftp.KeepAlive = true;
                ftp.Method = WebRequestMethods.Ftp.UploadFile;
                ftp.UseBinary = true;
                ftp.ContentLength = fi.Length;

                int buffLength = 2048;
                byte[] be = new byte[buffLength];
                int contentLen;
                using (FileStream fs = fi.OpenRead())
                {
                    using (Stream s = ftp.GetRequestStream())
                    {
                        contentLen = fs.Read(be, 0, buffLength);
                        while (contentLen != 0)
                        {
                            s.Write(be, 0, contentLen);
                            contentLen = fs.Read(be, 0, buffLength);
                        }
                        s.Close();
                    }
                    fs.Close();
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
    }

}

 

posted @ 2021-05-28 14:03  是晚安呀  阅读(472)  评论(0编辑  收藏  举报