C# 使用WebRequest 实现FTP常用功能

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;


namespace FtpDemo
{
    class FtpUpDown
    {
        #region 属性列表 Properties

        /// <summary>
        /// 服务器地址,可以是IP,也可以是FTP网址
        /// </summary>
        private string FtpServerAddress;

        /// <summary>
        /// 用户名
        /// </summary>
        private string FtpUserName;

        /// <summary>
        /// 用户密码
        /// </summary>
        private string FtpPassword;

        /// <summary>
        /// FTP请求
        /// </summary>
        private FtpWebRequest ftpRequest;

        #endregion

        #region 构造函数 Structure

        public FtpUpDown(string ftpServer, string ftpUserName, string ftpPassword)
            : this(ftpServer, ftpUserName, ftpPassword, 0)
        { }

        /// <summary>
        /// FTP上传下载
        /// </summary>
        /// <param name="ftpServer">服务器IP</param>
        /// <param name="ftpUserName">用户名</param>
        /// <param name="ftpPassword">密码</param>
        /// <param name="ftpServerPort">服务器端口</param>
        public FtpUpDown(string ftpServer, string ftpUserName, string ftpPassword, int ftpServerPort)
        {
            this.FtpServerAddress = ftpServer;
            this.FtpUserName = ftpUserName;
            this.FtpPassword = ftpPassword;

            //如果端口号大于零,则代表已经指定了端口号,否则使用默认端口。
            this.FtpServerAddress += (ftpServerPort > 0 ? string.Format(":{0}", ftpServerPort) : string.Empty);
        }

        #endregion

        #region 私有方法 Private methods

        /// <summary>
        /// 连接服务器
        /// </summary>
        private void Connect()
        {
            Connect("ftp://" + FtpServerAddress + "/");
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="path">FTP服务器要连接的路径</param>
        private void Connect(String path)
        {
            // 根据FTP路径创建FtpWebRequest对象
            ftpRequest = (FtpWebRequest)FtpWebRequest.Create(path);
          
            // 指定数据传输类型
            ftpRequest.UseBinary = true;
           
            //是否使用被动模式,主动FTP模式与被动FTP模式,可以参考下面的网页     
            ftpRequest.UsePassive = false;
         
            // ftp用户名和密码,创建与FTP进行连接的凭证。
            ftpRequest.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
        }

        /// <summary>
        /// 获得指定目录中的文件列表
        /// </summary>
        /// <param name="path">指定目录</param>
        /// <param name="WRMethods">发送到FTP服务器的命令【WebRequestMethods类中的值】</param>
        /// <returns></returns>
        private string[] GetFileList(string path, string WRMethods)
        {
            //最终要返回的文件(或目录)列表
            List<string> fileList = new List<string>();

            try
            {
                //连接指定目录
                Connect(path);
                //确定要执行的方法【读取目录?还是……?在此指定。】
                ftpRequest.Method = WRMethods;

                //接收服务器响应
                WebResponse response = ftpRequest.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名
                string line = reader.ReadLine();
                while (line != null)
                {
                    //循环读取并记录响应内容
                    fileList.Add(line);

                    line = reader.ReadLine();
                }

                reader.Close();
                response.Close();
                return fileList.ToArray();
            }
            catch (Exception ex)
            {
                //抛出错误,谁调用谁处理,偶就是不管。
                throw ex;
            }
        }

        #endregion

        #region 公共方法 Public Methods

        /// <summary>
        /// 1、测试连接
        /// </summary>
        /// <param name="errorInfo">返回的错误信息</param>
        /// <returns>是否测试成功</returns>
        public bool TestConnection(out string errorInfo)
        {
            errorInfo = string.Empty;
            try
            {
                //试图读取服务器端文件列表
                this.GetFileList();

                //读取成功,则代码连接无误
                return true;
            }
            catch (Exception ex)
            {
                //出错,则连接不对。
                errorInfo = "【连接错误】详细信息是:" + ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 2、从ftp服务器上获得根目录文件列表
        /// </summary>
        /// <returns></returns>
        public string[] GetFileList()
        {
            return GetFileList("ftp://" + FtpServerAddress + "/", WebRequestMethods.Ftp.ListDirectory);
        }

        /// <summary>
        /// 从ftp服务器上获得指定文件列表
        /// </summary>
        /// <param name="path">请求的路径【相对路径】</param>
        /// <returns></returns>
        public string[] GetFileList(string path)
        {
            return GetFileList("ftp://" + FtpServerAddress + "/" + path, WebRequestMethods.Ftp.ListDirectory);
        }                                                                

        /// <summary>
        /// 3、向服务器上传文件
        /// </summary>
        /// <param name="filename">本地文件路径</param>
        /// <param name="serverPath">服务器端的相对路径【例: uploads/myfiles 】两端不要加斜杠</param>
        public void Upload(string filename, string serverPath)
        {
            Upload(filename, serverPath, null);
        }

        /// <summary>
        /// 向服务器上传文件
        /// </summary>
        /// <param name="filename">本地文件路径</param>
        /// <param name="serverPath">服务器端的相对路径【例: uploads/myfiles 】两端不要加斜杠</param>
        /// <param name="transProcess">传输进度</param>
        public void Upload(string filename, string serverPath, TransmissionProcess transProcess)
        {
            //检查传输进度
            if (transProcess == null)
            {
                transProcess = new TransmissionProcess();
            }

            FileInfo fileInf = new FileInfo(filename);
            string uri = string.Format("ftp://{0}/{1}/{2}", FtpServerAddress, serverPath, fileInf.Name);

            transProcess.FileName = uri;//文件名
            transProcess.TotalBytes = fileInf.Length;//文件大小

            Connect(uri);//连接        
            //默认为true,连接不会被关闭
            //在一个命令之后被执行
            ftpRequest.KeepAlive = false;
            //指定执行什么命令
            ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
            //上传文件时通知服务器文件的大小
            ftpRequest.ContentLength = fileInf.Length;
            //缓冲大小设置为kb
            int buffLength = 2048;
            byte[] buff = new byte[buffLength];

            //打开一个文件流(System.IO.FileStream) 去读上传的文件
            FileStream fs = fileInf.OpenRead();

            try
            {
                //把上传的文件写入流
                Stream strm = ftpRequest.GetRequestStream();

                //每次读文件流的byte数目
                int contentLen = fs.Read(buff, 0, buffLength);

                //流内容没有结束
                while (contentLen != 0)
                {
                    //改变传输状态
                    if (transProcess.TransStatus != TransferStatus.InTransit)
                        transProcess.TransStatus = TransferStatus.InTransit;

                    //把内容从file stream 写入upload stream
                    strm.Write(buff, 0, contentLen);

                    //通知追加进度
                    transProcess.AppendBytes(contentLen);

                    contentLen = fs.Read(buff, 0, buffLength);
                }

                //关闭两个流
                strm.Close();
                fs.Close();

                //传输结束
                transProcess.TransStatus = TransferStatus.TranFinished;
            }
            catch (Exception ex)
            {
                transProcess.TransStatus = TransferStatus.Failed;
                throw new Exception(string.Format("向服务器上传文件时出错!/n/n{0}", ex.Message));
            }

        }

        /// <summary>
        /// 4、从ftp服务器下载文件
        /// </summary>
        /// <param name="filePath">要保存文件的本地目录</param>
        /// <param name="fileName">远程文件的路径【示例:uploads/myfile.rar】</param>
        /// <param name="overWriteLocalFile">是否覆盖本地文件</param>
        /// <param name="errorinfo">下载失败时,输出的错误信息</param>
        /// <returns>是否下载成功</returns>
        public bool Download(string filePath, string fileName, bool overWriteLocalFile, out string errorinfo)
        {
            return Download(filePath, fileName, overWriteLocalFile, null, out errorinfo);
        }

        /// <summary>
        /// 从ftp服务器下载文件
        /// </summary>
        /// <param name="filePath">要保存文件的本地目录</param>
        /// <param name="fileName">远程文件的路径【示例:uploads/myfile.rar】</param>
        /// <param name="overWriteLocalFile">是否覆盖本地文件</param>
        /// <param name="transProcess">传输进度</param>
        /// <param name="errorinfo">下载失败时,输出的错误信息</param>
        /// <returns>是否下载成功</returns>
        public bool Download(string filePath, string fileName, bool overWriteLocalFile, TransmissionProcess transProcess, out string errorinfo)
        {
            //检查传输进度
            if (transProcess == null)
            {
                transProcess = new TransmissionProcess();
            }

            errorinfo = string.Empty;
            try
            {
                String onlyFileName = Path.GetFileName(fileName);

                string newFileName = filePath + "//" + onlyFileName;

                if (File.Exists(newFileName) && overWriteLocalFile == false)
                {
                    transProcess.TransStatus = TransferStatus.Failed;
                    errorinfo = string.Format("本地文件{0}已存在,无法下载", newFileName);
                    return false;
                }

                //检查本地文件是否被占用
                if (File.Exists(newFileName))
                {
                    try
                    {
                        File.Move(newFileName, newFileName);
                    }
                    catch
                    {
                        transProcess.TransStatus = TransferStatus.Failed;
                        errorinfo = "本地文件被占用!无法覆盖!";
                        return false;
                    }
                }

                string url = "ftp://" + FtpServerAddress + "/" + fileName;
                Connect(url);//连接
                ftpRequest.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];

                transProcess.FileName = url;
                transProcess.TotalBytes = cl;
                //改变传输状态
                if (transProcess.TransStatus != TransferStatus.InTransit)
                    transProcess.TransStatus = TransferStatus.InTransit;

                readCount = ftpStream.Read(buffer, 0, bufferSize);
                transProcess.AppendBytes(readCount);

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

                //完成传输
                transProcess.FinishBytes();

                //下载成功
                return true;
            }
            catch (Exception ex)
            {
                transProcess.TransStatus = TransferStatus.Failed;
                errorinfo = string.Format("因{0},无法下载", ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 5、删除指定文件
        /// </summary>
        /// <param name="fileName">远程文件的路径【示例:uploads/myfile.rar】</param>
        public void DeleteFileName(string fileName)
        {
            string uri = "ftp://" + FtpServerAddress + "/" + fileName;
            try
            {
                Connect(uri);//连接        

                // 默认为true,连接不会被关闭
                // 在一个命令之后被执行
                ftpRequest.KeepAlive = false;

                // 指定执行什么命令
                ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                response.Close();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("删除文件“{0}”时出错!/n/n{1}", uri, ex.Message));
            }
        }

        /// <summary>
        /// 6、创建远程目录
        /// </summary>
        /// <param name="dirPath">远程文件夹路径</param>
        /// <returns></returns>
        public bool CreateDirectory(string dirPath)
        {
            try
            {
                string dirUri = "ftp://" + FtpServerAddress + "/" + dirPath;
                this.Connect(dirUri);
                ftpRequest.KeepAlive = false;
                ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
                ftpRequest.Proxy = null;
                FtpWebResponse uploadResponse = (FtpWebResponse)ftpRequest.GetResponse();
                uploadResponse.Close();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 7、删除目录
        /// </summary>
        /// <param name="dirPath">远程文件夹名【例如: uploads/oldDir】</param>
        /// <returns></returns>
        public bool DeleteDirectory(string dirPath)
        {
            try
            {
                string uri = "ftp://" + FtpServerAddress + "/" + dirPath;
                Connect(uri);//连接
                ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                response.Close();

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 8、获得文件大小
        /// </summary>
        /// <param name="filename">远程文件的路径【示例:uploads/myfile.rar】</param>
        /// <returns></returns>
        public long GetFileSize(string filename)
        {
            long fileSize = 0;
            string uri = "ftp://" + FtpServerAddress + "/" + filename;

            try
            {
                Connect(uri);//连接
                ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                fileSize = response.ContentLength;
                response.Close();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("获得文件“{0}”大小时出错!/n/n{1}", uri, ex.Message));
            }

            //成功返回大小
            return fileSize;
        }

        /// <summary>
        /// 9、重命名文件
        /// </summary>
        /// <param name="currentFilename">远程文件的路径【示例:uploads/myfile.rar】</param>
        /// <param name="newFilename">新名【不需要路径,但要包含后缀】</param>
        public void Rename(string currentFilename, string newFilename)
        {
            string uri = "ftp://" + FtpServerAddress + "/" + currentFilename;
            try
            {
                Connect(uri);//连接
                ftpRequest.Method = WebRequestMethods.Ftp.Rename;
                ftpRequest.RenameTo = newFilename;

                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                response.Close();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("重命名文件“{0}”大小时出错!/n/n{1}", uri, ex.Message));
            }
        }

        /// <summary>
        /// 10、获得根目录文件明晰
        /// </summary>
        /// <returns></returns>
        public string[] GetFilesDetailList()
        {
            return GetFilesDetailList(string.Empty);
        }

        /// <summary>
        /// 获得指定目录中的文件明晰
        /// </summary>
        /// <param name="path">指定目录【示例: upload/yan】</param>
        /// <returns></returns>
        public string[] GetFilesDetailList(string path)
        {
            return GetFileList("ftp://" + FtpServerAddress + "/" + path, WebRequestMethods.Ftp.ListDirectoryDetails);
        }


        /// <summary>
        /// 获取根目录下所有的文件夹列表(仅文件夹)
        /// </summary>
        /// <returns></returns>
        public string[] GetDirectoryList()
        {
   
            string[] drectory = GetFilesDetailList();
            string m = string.Empty;

            foreach (string str in drectory)
            {

                if (str.Trim().Substring(25, 1).ToUpper() == "D")
                {
                    m += str.Trim() + "/n";
                }
            }

            char[] n = new char[] { '/n' };
            return m.Split(n);
        }
     
        /// <summary>
        /// 获取指定目录下所有的文件夹列表(仅文件夹)
        /// </summary>
        /// <returns></returns>
        public string[] GetDirectoryList(string path)
        {
            //最终要返回的文件列表
            StringBuilder result = new StringBuilder();

            try
            {
                Connect("ftp://" + FtpServerAddress + "/");//连接
                ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                WebResponse response = ftpRequest.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);
                string line = reader.ReadLine();

                while (line != null)
                {
                    if (line.IndexOf("<DIR>") != -1)
                    {
                        result.Append(line);
                        result.Append("/n");
                    }
                    line = reader.ReadLine();
                }

                result.Remove(result.ToString().LastIndexOf('/n'), 1);
                reader.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            return result.ToString().Split('/n');  

        }
 

        /// <summary>  
        /// 获取根目录下文件列表(仅文件)  
        /// </summary>  
        /// <returns></returns>  
        public string[] GetFileNameList()  
        {
            //最终要返回的文件列表
            StringBuilder result = new StringBuilder(); 
 
            try 
            {
                Connect("ftp://" + FtpServerAddress + "/");//连接
                ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;  
                WebResponse response = ftpRequest.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);  
                string line = reader.ReadLine();  
               
                while (line != null)  
                {                         
                    if (line.IndexOf("<DIR>")==-1)  
                    {  
                        result.Append(Regex.Match(line, @"[/S]+ [/S]+", RegexOptions.IgnoreCase).Value.Split(' ')[1]);  
                        result.Append("/n");  
                    }  
                    line = reader.ReadLine();  
                }  
             
                result.Remove(result.ToString().LastIndexOf('/n'), 1);  
                reader.Close();  
                response.Close();  
            }  
            catch (Exception ex)  
            {  
                throw (ex);  
            }  
            return result.ToString().Split('/n');  

        } 


        #endregion

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值