zoukankan      html  css  js  c++  java
  • C# FTP操作

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Net;
      4 using System.IO;
      5 
      6 namespace FTP操作
      7 {
      8     /// <summary>
      9     /// FTP客户端操作类
     10     /// </summary>
     11     public class FtpClient
     12     {
     13         #region 构造函数
     14         /// <summary>
     15         /// 创建FTP工具
     16         /// <para>
     17         /// 默认不使用SSL,使用二进制传输方式,使用被动模式
     18         /// </para>
     19         /// </summary>
     20         /// <param name="host">主机名称</param>
     21         /// <param name="userId">用户名</param>
     22         /// <param name="password">密码</param>
     23         public FtpClient(string host, string userId, string password)
     24             : this(host, userId, password, 21, null, false, true, true)
     25         {
     26         }
     27 
     28         /// <summary>
     29         /// 创建FTP工具
     30         /// </summary>
     31         /// <param name="host">主机名称</param>
     32         /// <param name="userId">用户名</param>
     33         /// <param name="password">密码</param>
     34         /// <param name="port">端口</param>
     35         /// <param name="enableSsl">允许Ssl</param>
     36         /// <param name="proxy">代理</param>
     37         /// <param name="useBinary">允许二进制</param>
     38         /// <param name="usePassive">允许被动模式</param>
     39         public FtpClient(string host, string userId, string password, int port, IWebProxy proxy, bool enableSsl, bool useBinary, bool usePassive)
     40         {
     41             this.userId = userId;
     42             this.password = password;
     43             if (host.ToLower().StartsWith("ftp://"))
     44             {
     45                 this.host = host;
     46             }
     47             else
     48             {
     49                 this.host = "ftp://" + host;
     50             }
     51             this.port = port;
     52             this.proxy = proxy;
     53             this.enableSsl = enableSsl;
     54             this.useBinary = useBinary;
     55             this.usePassive = usePassive;
     56         }
     57         #endregion
     58 
     59         #region 主机
     60         private string host = string.Empty;
     61         /// <summary>
     62         /// 主机
     63         /// </summary>
     64         public string Host
     65         {
     66             get
     67             {
     68                 return this.host ?? string.Empty;
     69             }
     70         }
     71         #endregion
     72 
     73         #region 登录用户名
     74         private string userId = string.Empty;
     75         /// <summary>
     76         /// 登录用户名
     77         /// </summary>
     78         public string UserId
     79         {
     80             get
     81             {
     82                 return this.userId;
     83             }
     84         }
     85         #endregion
     86 
     87         #region 密码
     88         private string password = string.Empty;
     89         /// <summary>
     90         /// 密码
     91         /// </summary>
     92         public string Password
     93         {
     94             get
     95             {
     96                 return this.password;
     97             }
     98         }
     99         #endregion
    100 
    101         #region 代理
    102         IWebProxy proxy = null;
    103         /// <summary>
    104         /// 代理
    105         /// </summary>
    106         public IWebProxy Proxy
    107         {
    108             get
    109             {
    110                 return this.proxy;
    111             }
    112             set
    113             {
    114                 this.proxy = value;
    115             }
    116         }
    117         #endregion
    118 
    119         #region 端口
    120         private int port = 21;
    121         /// <summary>
    122         /// 端口
    123         /// </summary>
    124         public int Port
    125         {
    126             get
    127             {
    128                 return port;
    129             }
    130             set
    131             {
    132                 this.port = value;
    133             }
    134         }
    135         #endregion
    136 
    137         #region 设置是否允许Ssl
    138         private bool enableSsl = false;
    139         /// <summary>
    140         /// EnableSsl 
    141         /// </summary>
    142         public bool EnableSsl
    143         {
    144             get
    145             {
    146                 return enableSsl;
    147             }
    148         }
    149         #endregion
    150 
    151         #region 使用被动模式
    152         private bool usePassive = true;
    153         /// <summary>
    154         /// 被动模式
    155         /// </summary>
    156         public bool UsePassive
    157         {
    158             get
    159             {
    160                 return usePassive;
    161             }
    162             set
    163             {
    164                 this.usePassive = value;
    165             }
    166         }
    167         #endregion
    168 
    169         #region 二进制方式
    170         private bool useBinary = true;
    171         /// <summary>
    172         /// 二进制方式
    173         /// </summary>
    174         public bool UseBinary
    175         {
    176             get
    177             {
    178                 return useBinary;
    179             }
    180             set
    181             {
    182                 this.useBinary = value;
    183             }
    184         }
    185         #endregion
    186 
    187         #region 远端路径
    188         private string remotePath = "/";
    189         /// <summary>
    190         /// 远端路径
    191         /// <para>
    192         ///     返回FTP服务器上的当前路径(可以是 / 或 /a/../ 的形式)
    193         /// </para>
    194         /// </summary>
    195         public string RemotePath
    196         {
    197             get
    198             {
    199                 return remotePath;
    200             }
    201             set
    202             {
    203                 string result = "/";
    204                 if (!string.IsNullOrEmpty(value) && value != "/")
    205                 {
    206                     result = "/" + value.TrimStart('/').TrimEnd('/') + "/";
    207                 }
    208                 this.remotePath = result;
    209             }
    210         }
    211         #endregion
    212 
    213         #region 创建一个FTP连接
    214         /// <summary>
    215         /// 创建一个FTP请求
    216         /// </summary>
    217         /// <param name="url">请求地址</param>
    218         /// <param name="method">请求方法</param>
    219         /// <returns>FTP请求</returns>
    220         private FtpWebRequest CreateRequest(string url, string method)
    221         {
    222             //建立连接
    223             FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
    224             request.Credentials = new NetworkCredential(this.userId, this.password);
    225             request.Proxy = this.proxy;
    226             request.KeepAlive = false;//命令执行完毕之后关闭连接
    227             request.UseBinary = useBinary;
    228             request.UsePassive = usePassive;
    229             request.EnableSsl = enableSsl;
    230             request.Method = method;
    231             return request;
    232         }
    233         #endregion
    234 
    235         #region 上传一个文件到远端路径下
    236         /// <summary>
    237         /// 把文件上传到FTP服务器的RemotePath下
    238         /// </summary>
    239         /// <param name="localFile">本地文件信息</param>
    240         /// <param name="remoteFileName">要保存到FTP文件服务器上的名称</param>
    241         public bool Upload(FileInfo localFile, string remoteFileName)
    242         {
    243             bool result = false;
    244             if (localFile.Exists)
    245             {
    246                 string url = Host.TrimEnd('/') + RemotePath + remoteFileName;
    247                 FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.UploadFile);
    248 
    249                 //上传数据
    250                 using (Stream rs = request.GetRequestStream())
    251                 using (FileStream fs = localFile.OpenRead())
    252                 {
    253                     byte[] buffer = new byte[4096];//4K
    254                     int count = fs.Read(buffer, 0, buffer.Length);
    255                     while (count > 0)
    256                     {
    257                         rs.Write(buffer, 0, count);
    258                         count = fs.Read(buffer, 0, buffer.Length);
    259                     }
    260                     fs.Close();
    261                     result = true;
    262                 }
    263                 return result;
    264             }
    265             throw new Exception(string.Format("本地文件不存在,文件路径:{0}", localFile.FullName));
    266         }
    267         #endregion
    268 
    269         #region 从FTP服务器上下载文件
    270         /// <summary>
    271         /// 从当前目录下下载文件
    272         /// <para>
    273         /// 如果本地文件存在,则从本地文件结束的位置开始下载.
    274         /// </para>
    275         /// </summary>
    276         /// <param name="serverName">服务器上的文件名称</param>
    277         /// <param name="localName">本地文件名称</param>
    278         /// <returns>返回一个值,指示是否下载成功</returns>
    279         public bool Download(string serverName, string localName)
    280         {
    281             bool result = false;
    282             using (FileStream fs = new FileStream(localName, FileMode.OpenOrCreate)) //创建或打开本地文件
    283             {
    284                 //建立连接
    285                 string url = Host.TrimEnd('/') + RemotePath + serverName;
    286                 FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.DownloadFile);
    287                 request.ContentOffset = fs.Length;
    288                 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    289                 {
    290                     fs.Position = fs.Length;
    291                     byte[] buffer = new byte[4096];//4K
    292                     int count = response.GetResponseStream().Read(buffer, 0, buffer.Length);
    293                     while (count > 0)
    294                     {
    295                         fs.Write(buffer, 0, count);
    296                         count = response.GetResponseStream().Read(buffer, 0, buffer.Length);
    297                     }
    298                     response.GetResponseStream().Close();
    299                 }
    300                 result = true;
    301             }
    302             return result;
    303         }
    304         #endregion
    305 
    306         #region 重命名FTP服务器上的文件
    307         /// <summary>
    308         /// 文件更名
    309         /// </summary>
    310         /// <param name="oldFileName">原文件名</param>
    311         /// <param name="newFileName">新文件名</param>
    312         /// <returns>返回一个值,指示更名是否成功</returns>
    313         public bool Rename(string oldFileName, string newFileName)
    314         {
    315             bool result = false;
    316             //建立连接
    317             string url = Host.TrimEnd('/') + RemotePath + oldFileName;
    318             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.Rename);
    319             request.RenameTo = newFileName;
    320             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    321             {
    322                 result = true;
    323             }
    324             return result;
    325         }
    326         #endregion
    327 
    328         #region 从当前目录下获取文件列表
    329         /// <summary>
    330         /// 获取当前目录下文件列表
    331         /// </summary>
    332         /// <returns></returns>
    333         public List<string> GetFileList()
    334         {
    335             List<string> result = new List<string>();
    336             //建立连接
    337             string url = Host.TrimEnd('/') + RemotePath;
    338             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.ListDirectory);
    339             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    340             {
    341                 StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名
    342                 string line = reader.ReadLine();
    343                 while (line != null)
    344                 {
    345                     result.Add(line);
    346                     line = reader.ReadLine();
    347                 }
    348             }
    349             return result;
    350         }
    351         #endregion
    352 
    353         #region 从FTP服务器上获取文件和文件夹列表
    354         /// <summary>
    355         /// 获取详细列表
    356         /// </summary>
    357         /// <returns></returns>
    358         public List<string> GetFileDetails()
    359         {
    360             List<string> result = new List<string>();
    361             //建立连接
    362             string url = Host.TrimEnd('/') + RemotePath;
    363             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.ListDirectoryDetails);
    364             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    365             {
    366                 StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名
    367                 string line = reader.ReadLine();
    368                 while (line != null)
    369                 {
    370                     result.Add(line);
    371                     line = reader.ReadLine();
    372                 }
    373             }
    374             return result;
    375         }
    376         #endregion
    377 
    378         #region 从FTP服务器上删除文件
    379         /// <summary>
    380         /// 删除FTP服务器上的文件
    381         /// </summary>
    382         /// <param name="fileName">文件名称</param>
    383         /// <returns>返回一个值,指示是否删除成功</returns>
    384         public bool DeleteFile(string fileName)
    385         {
    386             bool result = false;
    387             //建立连接
    388             string url = Host.TrimEnd('/') + RemotePath + fileName;
    389             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.DeleteFile);
    390             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    391             {
    392                 result = true;
    393             }
    394 
    395             return result;
    396         }
    397         #endregion
    398 
    399         #region 在FTP服务器上创建目录
    400         /// <summary>
    401         /// 在当前目录下创建文件夹
    402         /// </summary>
    403         /// <param name="dirName">文件夹名称</param>
    404         /// <returns>返回一个值,指示是否创建成功</returns>
    405         public bool MakeDirectory(string dirName)
    406         {
    407             bool result = false;
    408             //建立连接
    409             string url = Host.TrimEnd('/') + RemotePath + dirName;
    410             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.MakeDirectory);
    411             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    412             {
    413                 result = true;
    414             }
    415             return result;
    416         }
    417         #endregion
    418 
    419         #region 从FTP服务器上删除目录
    420         /// <summary>
    421         /// 删除文件夹
    422         /// </summary>
    423         /// <param name="dirName">文件夹名称</param>
    424         /// <returns>返回一个值,指示是否删除成功</returns>
    425         public bool DeleteDirectory(string dirName)
    426         {
    427             bool result = false;
    428             //建立连接
    429             string url = Host.TrimEnd('/') + RemotePath + dirName;
    430             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.RemoveDirectory);
    431             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    432             {
    433                 result = true;
    434             }
    435             return result;
    436         }
    437         #endregion
    438 
    439         #region 从FTP服务器上获取文件大小
    440         /// <summary>
    441         /// 获取文件大小
    442         /// </summary>
    443         /// <param name="fileName"></param>
    444         /// <returns></returns>
    445         public long GetFileSize(string fileName)
    446         {
    447             long result = 0;
    448             //建立连接
    449             string url = Host.TrimEnd('/') + RemotePath + fileName;
    450             FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.GetFileSize);
    451             using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    452             {
    453                 result = response.ContentLength;
    454             }
    455 
    456             return result;
    457         }
    458         #endregion
    459 
    460         #region 给FTP服务器上的文件追加内容
    461         /// <summary>
    462         /// 给FTP服务器上的文件追加内容
    463         /// </summary>
    464         /// <param name="localFile">本地文件</param>
    465         /// <param name="remoteFileName">FTP服务器上的文件</param>
    466         /// <returns>返回一个值,指示是否追加成功</returns>
    467         public bool Append(FileInfo localFile, string remoteFileName)
    468         {
    469             if (localFile.Exists)
    470             {
    471                 using (FileStream fs = new FileStream(localFile.FullName, FileMode.Open))
    472                 {
    473                     return Append(fs, remoteFileName);
    474                 }
    475             }
    476             throw new Exception(string.Format("本地文件不存在,文件路径:{0}", localFile.FullName));
    477         }
    478 
    479         /// <summary>
    480         /// 给FTP服务器上的文件追加内容
    481         /// </summary>
    482         /// <param name="stream">数据流(可通过设置偏移来实现从特定位置开始上传)</param>
    483         /// <param name="remoteFileName">FTP服务器上的文件</param>
    484         /// <returns>返回一个值,指示是否追加成功</returns>
    485         public bool Append(Stream stream, string remoteFileName)
    486         {
    487             bool result = false;
    488             if (stream != null && stream.CanRead)
    489             {
    490                 //建立连接
    491                 string url = Host.TrimEnd('/') + RemotePath + remoteFileName;
    492                 FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.AppendFile);
    493                 using (Stream rs = request.GetRequestStream())
    494                 {
    495                     //上传数据
    496                     byte[] buffer = new byte[4096];//4K
    497                     int count = stream.Read(buffer, 0, buffer.Length);
    498                     while (count > 0)
    499                     {
    500                         rs.Write(buffer, 0, count);
    501                         count = stream.Read(buffer, 0, buffer.Length);
    502                     }
    503                     result = true;
    504                 }
    505             }
    506             return result;
    507         }
    508         #endregion
    509 
    510         #region 获取FTP服务器上的当前路径
    511         /// <summary>
    512         /// 获取FTP服务器上的当前路径
    513         /// </summary>
    514         public string CurrentDirectory
    515         {
    516             get
    517             {
    518                 string result = string.Empty;
    519                 string url = Host.TrimEnd('/') + RemotePath;
    520                 FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.PrintWorkingDirectory);
    521                 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
    522                 {
    523                     string temp = response.StatusDescription;
    524                     int start = temp.IndexOf('"') + 1;
    525                     int end = temp.LastIndexOf('"');
    526                     if (end >= start)
    527                     {
    528                         result = temp.Substring(start, end - start);
    529                     }
    530                 }
    531                 return result;
    532 
    533             }
    534         }
    535         #endregion
    536 
    537         #region 检查当前路径上是否存在某个文件
    538         /// <summary>
    539         /// 检查文件是否存在
    540         /// </summary>
    541         /// <param name="fileName">要检查的文件名</param>
    542         /// <returns>返回一个值,指示要检查的文件是否存在</returns>
    543         public bool CheckFileExist(string fileName)
    544         {
    545             bool result = false;
    546             if (fileName != null && fileName.Trim().Length > 0)
    547             {
    548                 fileName = fileName.Trim();
    549                 List<string> files = GetFileList();
    550                 if (files != null && files.Count > 0)
    551                 {
    552                     foreach (string file in files)
    553                     {
    554                         if (file.ToLower() == fileName.ToLower())
    555                         {
    556                             result = true;
    557                             break;
    558                         }
    559                     }
    560                 }
    561             }
    562             return result;
    563         }
    564         #endregion
    565 
    566     }
    567 }
    568 
    569 /*
    570 FTP全状态码查询词典
    571   
    572 1xx - 肯定的初步答复
    573 这些状态代码指示一项操作已经成功开始,但客户端希望在继续操作新命令前得到另一个答复。 • 110 重新启动标记答复。 
    574 • 120 服务已就绪,在 nnn 分钟后开始。 
    575 • 125 数据连接已打开,正在开始传输。 
    576 • 150 文件状态正常,准备打开数据连接。 
    577 
    578 2xx - 肯定的完成答复
    579 一项操作已经成功完成。客户端可以执行新命令。 • 200 命令确定。 
    580 • 202 未执行命令,站点上的命令过多。 
    581 • 211 系统状态,或系统帮助答复。 
    582 • 212 目录状态。 
    583 • 213 文件状态。 
    584 • 214 帮助消息。 
    585 • 215 NAME 系统类型,其中,NAME 是 Assigned Numbers 文档中所列的正式系统名称。 
    586 • 220 服务就绪,可以执行新用户的请求。 
    587 • 221 服务关闭控制连接。如果适当,请注销。 
    588 • 225 数据连接打开,没有进行中的传输。 
    589 • 226 关闭数据连接。请求的文件操作已成功(例如,传输文件或放弃文件)。 
    590 • 227 进入被动模式 (h1,h2,h3,h4,p1,p2)。 
    591 • 230 用户已登录,继续进行。 
    592 • 250 请求的文件操作正确,已完成。 
    593 • 257 已创建“PATHNAME”。 
    594 
    595 3xx - 肯定的中间答复
    596 该命令已成功,但服务器需要更多来自客户端的信息以完成对请求的处理。 • 331 用户名正确,需要密码。 
    597 • 332 需要登录帐户。 
    598 • 350 请求的文件操作正在等待进一步的信息。 
    599 
    600 4xx - 瞬态否定的完成答复
    601 该命令不成功,但错误是暂时的。如果客户端重试命令,可能会执行成功。 • 421 服务不可用,正在关闭控制连接。如果服务确定它必须关闭,将向任何命令发送这一应答。 
    602 • 425 无法打开数据连接。 
    603 • 426 Connection closed; transfer aborted. 
    604 • 450 未执行请求的文件操作。文件不可用(例如,文件繁忙)。 
    605 • 451 请求的操作异常终止:正在处理本地错误。 
    606 • 452 未执行请求的操作。系统存储空间不够。 
    607 
    608 5xx - 永久性否定的完成答复
    609 该命令不成功,错误是永久性的。如果客户端重试命令,将再次出现同样的错误。 • 500 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误。 
    610 • 501 在参数中有语法错误。 
    611 • 502 未执行命令。 
    612 • 503 错误的命令序列。 
    613 • 504 未执行该参数的命令。 
    614 • 530 未登录。 
    615 • 532 存储文件需要帐户。 
    616 • 550 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)。 
    617 • 551 请求的操作异常终止:未知的页面类型。 
    618 • 552 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)。 
    619 • 553 未执行请求的操作。不允许的文件名。 
    620 常见的 FTP 状态代码及其原因
    621 • 150 - FTP 使用两个端口:21 用于发送命令,20 用于发送数据。状态代码 150 表示服务器准备在端口 20 上打开新连接,发送一些数据。 
    622 • 226 - 命令在端口 20 上打开数据连接以执行操作,如传输文件。该操作成功完成,数据连接已关闭。 
    623 • 230 - 客户端发送正确的密码后,显示该状态代码。它表示用户已成功登录。 
    624 • 331 - 客户端发送用户名后,显示该状态代码。无论所提供的用户名是否为系统中的有效帐户,都将显示该状态代码。 
    625 • 426 - 命令打开数据连接以执行操作,但该操作已被取消,数据连接已关闭。 
    626 • 530 - 该状态代码表示用户无法登录,因为用户名和密码组合无效。如果使用某个用户帐户登录,可能键入错误的用户名或密码,也可能选择只允许匿名访问。如果使用匿名帐户登录,IIS 的配置可能拒绝匿名访问。 
    627 • 550 - 命令未被执行,因为指定的文件不可用。例如,要 GET 的文件并不存在,或试图将文件 PUT 到您没有写入权限的目录。
    628 */
  • 相关阅读:
    Qt之QFileSystemWatcher
    Qt之qSetMessagePattern
    物联网操作系统HelloX V1.80测试版发布
    CoreOS Linux available in China
    等火车
    HTTP 简介
    建造模式Builder
    MariaDB exists 学习
    javascript 中 typeof 的使用
    Java字符串null相加
  • 原文地址:https://www.cnblogs.com/skynetfy/p/3340125.html
Copyright © 2011-2022 走看看