zoukankan      html  css  js  c++  java
  • 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;
            }

        }

  • 相关阅读:
    Zend_Controller架构
    PHP构造函数的执行顺序
    MySQL性能优化的最佳21条经验
    MySQL触发器学习总结
    使用Zend_Auth和Zend_Acl进行登录认证及根据用户角色进行权限控制
    手动释放你的资源(Please release resources manually)
    InfoPath/SharePoint/WebParts项目组章程 无为而为
    解决错误:sql_variant is incompatible with xml (ASP.NET 2.0 / XML数据类型 ) 无为而为
    使用ISA2004发布SharePoint网站到外部网,需要使用链接转换 无为而为
    InfoPath/SharePoint/WebParts项目组 下一步的工作和团队未来的规划给队员的公开信 无为而为
  • 原文地址:https://www.cnblogs.com/dashi/p/4034725.html
Copyright © 2011-2022 走看看