• 封装FTP类


    using System;
     using System.Net;
     using System.Net.Sockets;
     using System.Text;
     using System.IO;
    using System.Collections.Generic;
    
    namespace FTP
     {
          /// <summary>
          /// FTP 操作类 Create by joe 20140520
          /// </summary>
          public class FTP
          {
               private string strRemoteHost;
               private int strRemotePort;
               private string strRemotePath;
               private string strRemoteUser;
               private string strRemotePass;
               private Boolean bConnected;
             
              #region 内部变量
               /// <summary>
               /// 服务器返回的应答信息(包含应答码)
               /// </summary>
               private string strMsg;
    
               /// <summary>
               /// 服务器返回的应答信息(包含应答码)
               /// </summary>
               private string strReply;
    
               /// <summary>
               /// 服务器返回的应答码
               /// </summary>
               private int iReplyCode;
    
               /// <summary>
               /// 进行控制连接的socket
               /// </summary>
               private Socket socketControl;
    
               /// <summary>
               /// 传输模式
               /// </summary>
               private TransferType trType;
    
               /// <summary>
               /// 传输模式:二进制类型、ASCII类型
               /// </summary>
               public enum TransferType
               {
                    /// <summary>
                    /// Binary
                    /// </summary>
                    Binary,
                    /// <summary>
                    /// ASCII
                    /// </summary>
                    ASCII
               };
             
              /// <summary>
               /// 接收和发送数据的缓冲区
               /// </summary>
               private static int BLOCK_SIZE = 512;
               Byte[] buffer = new Byte[ BLOCK_SIZE];
               /// <summary>
               /// 编码方式
               /// </summary>
               Encoding ASCII = Encoding.Default;
               #endregion
             
              #region 内部函数
             
              #region 构造函数
    
               /// <summary>
               /// 缺省构造函数(默认端口为21)
               /// </summary>
               public FTP()
               {
                    strRemoteHost  = "";
                    strRemotePath  = "";
                    strRemoteUser  = "";
                    strRemotePass  = "";
                    strRemotePort  = 21;
                    bConnected     = false;
               }
             
              /// <summary>
               /// 构造函数
               /// </summary>
               /// <param name="remoteHost"></param>
               /// <param name="remotePath"></param>
               /// <param name="remoteUser"></param>
               /// <param name="remotePass"></param>
               /// <param name="remotePort"></param>
               public FTP( string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort )
               {
                strRemoteHost  = remoteHost;
                strRemotePath  = remotePath;
                strRemoteUser  = remoteUser;
                strRemotePass  = remotePass;
                strRemotePort  = remotePort;
                Connect();
               }
    
              /// <summary>
              /// 实例化对象类(默认端口为21)
              /// </summary>
              /// <param name="remoteHost"></param>
              /// <param name="remotePath"></param>
              /// <param name="remoteUser"></param>
              /// <param name="remotePass"></param>
               public FTP( string remoteHost, string remotePath, string remoteUser, string remotePass)
               {
                strRemoteHost  = remoteHost;
                strRemotePath  = remotePath;
                strRemoteUser  = remoteUser;
                strRemotePass  = remotePass;
                strRemotePort  = 21;
                Connect();
               }
               #endregion
             
              #region 登陆
               /// <summary>
               /// FTP服务器IP地址
               /// </summary>      
               public string RemoteHost
               {
                    get
                    {
                         return strRemoteHost;
                    }
                    set
                    {
                        strRemoteHost = value;
                    }
               }
    
               /// <summary>
               /// FTP服务器端口
               /// </summary>
               public int RemotePort
               {
                    get
                    {
                        return strRemotePort;
                    }
                    set
                    {
                        strRemotePort = value;
                    }
               }
    
               /// <summary>
               /// 当前服务器目录
               /// </summary>
               public string RemotePath
               {
                get
                {
                 return strRemotePath;
                }
                set
                {
                 strRemotePath = value;
                }
               }
    
               /// <summary>
               /// 登录用户账号
               /// </summary>
               public string RemoteUser
               {
                set
                {
                 strRemoteUser = value;
                }
               }
    
               /// <summary>
               /// 用户登录密码
               /// </summary>
               public string RemotePass
               {
                set
                {
                 strRemotePass = value;
                }
               }
             
              /// <summary>
               /// 是否登录
               /// </summary>
               public bool Connected
               {
                    get
                    {
                        return bConnected;
                    }
               }
               #endregion
             
              #region 链接
               /// <summary>
               /// 建立连接 
               /// </summary>
               public void Connect()
               {
                    socketControl = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                    IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort);
                    // 链接
                    try
                    {
                        socketControl.Connect(ep);
                    }
                    catch(Exception)
                    {
                        throw new IOException("Couldn't connect to remote server");
                    }
                 
                   // 获取应答码
                    ReadReply();
                    if(iReplyCode != 220)
                    {
                         DisConnect();
                         throw new IOException(strReply.Substring(4));
                    }
                 
                   // 登陆
                    SendCommand("USER "+strRemoteUser);
                    if( !(iReplyCode == 331 || iReplyCode == 230) )
                    {
                         CloseSocketConnect();//关闭连接
                         throw new IOException(strReply.Substring(4));
                    }
                    if( iReplyCode != 230 )
                    {
                         SendCommand("PASS "+strRemotePass);
                         if( !(iReplyCode == 230 || iReplyCode == 202) )
                         {
                              CloseSocketConnect();//关闭连接
                              throw new IOException(strReply.Substring(4));
                         }
                    }
                    bConnected = true;
                 
                   // 切换到目录
                    ChDir(strRemotePath);
               }
             
    
              /// <summary>
               /// 关闭连接
               /// </summary>
               public void DisConnect()
               {
                if( socketControl != null )
                {
                 SendCommand("QUIT");
                }
                CloseSocketConnect();
               }
             
              #endregion
             
              #region 传输模式
             
              /// <summary>
               /// 设置传输模式
               /// </summary>
               /// <param name="ttType">传输模式</param>
               public void SetTransferType(TransferType ttType)
               {
                if(ttType == TransferType.Binary)
                {
                 SendCommand("TYPE I");//binary类型传输
                }
                else
                {
                 SendCommand("TYPE A");//ASCII类型传输
                }
                if (iReplyCode != 200)
                {
                 throw new IOException(strReply.Substring(4));
                }
                else
                {
                 trType = ttType;
                }
               }
             
    
              /// <summary>
               /// 获得传输模式
               /// </summary>
               /// <returns>传输模式</returns>
               public TransferType GetTransferType()
               {
                return trType;
               }
             
              #endregion
             
              #region 文件操作
               /// <summary>
               /// 获得文件列表
               /// </summary>
               /// <param name="strMask">文件名的匹配字符串</param>
               /// <returns></returns>
             public string[] Dir(string strMask)
               {
                // 建立链接
                if(!bConnected)
                {
                 Connect();
                }
             
               //建立进行数据连接的socket
                Socket socketData = CreateDataSocket();
             
               //传送命令
                SendCommand("NLST " + strMask);
             
               //分析应答代码
                if(!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226))
                {
                 throw new IOException(strReply.Substring(4));
                }
             
               //获得结果
                strMsg = "";
                while(true)
                {
                 int iBytes = socketData.Receive(buffer, buffer.Length, 0);
                 strMsg += ASCII.GetString(buffer, 0, iBytes);
                 if(iBytes < buffer.Length)
                 {
                  break;
                 }
                }
                char[] seperator = {'
    '};
                string[] strsFileList = strMsg.Split(seperator);
                socketData.Close();//数据socket关闭时也会有返回码
                if(iReplyCode != 226)
                {
                 ReadReply();
                 if(iReplyCode != 226)
                 {
                  throw new IOException(strReply.Substring(4));
                 }
                }
                return strsFileList;
               }
    
               /// <summary>
               /// 从ftp服务器上获得文件列表
               /// </summary>
               /// <param name="RequedstPath">服务器下的相对路径</param>
               /// <returns></returns>
               public  List<string> GetFile(string RequedstPath)
               {
                   List<string> strs = new List<string>();
                   try
                   {
                       string uri = "ftp://" + strRemoteHost + ":" + strRemotePort.ToString() + "/" + RequedstPath;   //目标路径 path为服务器地址
                       FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                       // ftp用户名和密码
                       reqFTP.Credentials = new NetworkCredential(strRemoteUser, strRemotePass);
                       reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                       WebResponse response = reqFTP.GetResponse();
                       StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名
    
                       string line = reader.ReadLine();
                       while (line != null)
                       {
                           if (!line.Contains("<DIR>"))
                           {
                               string msg = line.Substring(39).Trim();
                               strs.Add(msg);
                           }
                           line = reader.ReadLine();
                       }
                       reader.Close();
                       response.Close();
                       return strs;
                   }
                   catch (Exception ex)
                   {
                       throw new IOException("获取文件出错:" + ex.Message);
                   }
               }
    
              /// <summary>
               /// 获取文件大小
               /// </summary>
               /// <param name="strFileName">文件名</param>
               /// <returns>文件大小</returns>
               private long GetFileSize(string strFileName)
               {
                if(!bConnected)
                {
                 Connect();
                }
                SendCommand("SIZE " + Path.GetFileName(strFileName));
                long lSize=0;
                if(iReplyCode == 213)
                {
                 lSize = Int64.Parse(strReply.Substring(4));
                }
                else
                {
                 throw new IOException(strReply.Substring(4));
                }
                return lSize;
               }
             
    
              /// <summary>
               /// 删除
               /// </summary>
               /// <param name="strFileName">待删除文件名</param>
               public void Delete(string strFileName)
               {
                if(!bConnected)
                {
                 Connect();
                }
                SendCommand("DELE "+strFileName);
                if(iReplyCode != 250)
                {
                 throw new IOException(strReply.Substring(4));
                }
               }
             
    
              /// <summary>
               /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
               /// </summary>
               /// <param name="strOldFileName">旧文件名</param>
               /// <param name="strNewFileName">新文件名</param>
               public void Rename(string strOldFileName,string strNewFileName)
               {
                if(!bConnected)
                {
                 Connect();
                }
                SendCommand("RNFR "+strOldFileName);
                if(iReplyCode != 350)
                {
                 throw new IOException(strReply.Substring(4));
                }
                //  如果新文件名与原有文件重名,将覆盖原有文件
                SendCommand("RNTO "+strNewFileName);
                if(iReplyCode != 250)
                {
                 throw new IOException(strReply.Substring(4));
                }
               }
               #endregion
             
              #region 上传和下载
               /// <summary>
               /// 下载一批文件
               /// </summary>
               /// <param name="strFileNameMask">文件名的匹配字符串</param>
               /// <param name="strFolder">本地目录(不得以结束)</param>
               public void Get(string strFileNameMask,string strFolder)
               {
                if(!bConnected)
                {
                 Connect();
                }
                List<string> strFiles = GetFile(strFileNameMask);
                foreach(string strFile in strFiles)
                {
                 if(!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串
                 {
                     Get(strFileNameMask, strFile, strFolder, strFile);
                 }
                }
               }
             
    
              /// <summary>
               /// 下载一个文件
               /// </summary>
               /// <param name="strRemoteFileName">要下载的文件名</param>
               /// <param name="strFolder">本地目录(不得以结束)</param>
               /// <param name="strLocalFileName">保存在本地时的文件名</param>
               public void Get(string strPath,string strRemoteFileName,string strFolder,string strLocalFileName)
               {
                if(!bConnected)
                {
                 Connect();
                }
                SetTransferType(TransferType.Binary);
                if (strLocalFileName.Equals(""))
                {
                 strLocalFileName = strRemoteFileName;
                }
                if(!File.Exists(strLocalFileName))
                {
                 Stream st = File.Create(strLocalFileName);
                 st.Close();
                }
                FileStream output = new FileStream(strFolder + "\" + strLocalFileName,FileMode.Create);
                Socket socketData = CreateDataSocket();
                SendCommand("RETR " + strPath + "\" + strRemoteFileName);
                if(!(iReplyCode == 150 || iReplyCode == 125
                 || iReplyCode == 226 || iReplyCode == 250))
                {
                 throw new IOException(strReply.Substring(4));
                }
                while(true)
                {
                 int iBytes = socketData.Receive(buffer, buffer.Length, 0);
                 output.Write(buffer,0,iBytes);
                 if(iBytes <= 0)
                 {
                  break;
                 }
                }
                output.Close();
                if (socketData.Connected)
                {
                 socketData.Close();
                }
                if(!(iReplyCode == 226 || iReplyCode == 250))
                {
                 ReadReply();
                 if(!(iReplyCode == 226 || iReplyCode == 250))
                 {
                  throw new IOException(strReply.Substring(4));
                 }
                }
               }
             
    
              /// <summary>
               /// 上传一批文件
               /// </summary>
               /// <param name="strFolder">本地目录(不得以结束)</param>
               /// <param name="strFileNameMask">文件名匹配字符(可以包含*和?)</param>
               public void Put(string strFolder,string strFileNameMask)
               {
                string[] strFiles = Directory.GetFiles(strFolder,strFileNameMask);
                foreach(string strFile in strFiles)
                {
                 //strFile是完整的文件名(包含路径)
                 Put(strFile);
                }
               }
    
               /// <summary>
               /// 上传一个文件
               /// </summary>
               /// <param name="strFileName">本地文件名</param>
               public void Put(string strFileName)
               {
                   if (!bConnected)
                   {
                       Connect();
                   }
                   Socket socketData = CreateDataSocket();
                   SendCommand("STOR " + Path.GetFileName(strFileName));
                   if (!(iReplyCode == 125 || iReplyCode == 150))
                   {
                       throw new IOException(strReply.Substring(4));
                   }
                   FileStream input = new
                    FileStream(strFileName, FileMode.Open);
                   int iBytes = 0;
                   while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0)
                   {
                       socketData.Send(buffer, iBytes, 0);
                   }
                   input.Close();
                   if (socketData.Connected)
                   {
                       socketData.Close();
                   }
                   if (!(iReplyCode == 226 || iReplyCode == 250))
                   {
                       ReadReply();
                       if (!(iReplyCode == 226 || iReplyCode == 250))
                       {
                           throw new IOException(strReply.Substring(4));
                       }
                   }
               }
    
              #endregion
    
              #region 目录操作
               /// <summary>
               /// 创建目录
               /// </summary>
               /// <param name="strDirName">目录名</param>
               public void MkDir(string strDirName)
               {
                   if (!bConnected)
                   {
                       Connect();
                   }
                   SendCommand("MKD " + strDirName);
                   if (iReplyCode != 257)
                   {
                       throw new IOException(strReply.Substring(4));
                   }
               }
    
    
               /// <summary>
               /// 删除目录
               /// </summary>
               /// <param name="strDirName">目录名</param>
               public void RmDir(string strDirName)
               {
                   if (!bConnected)
                   {
                       Connect();
                   }
                   SendCommand("RMD " + strDirName);
                   if (iReplyCode != 250)
                   {
                       throw new IOException(strReply.Substring(4));
                   }
               }
    
              /// <summary>
              ///  检测目录是否存在
              /// </summary>
              /// <param name="strDirName"></param>
              /// <returns></returns>
              public bool DirIsExist(string strDirName)
              {
                  try
                  {
                      Uri uri = new Uri("ftp://" + strRemoteHost + ":" + strRemotePort.ToString() + "/" + strDirName + "/");
                      if (!DirectoryIsExist(uri, strRemoteUser, strRemotePass))
                      {
                          return false;
                      }
                      else
                      {
                          return true;
                      }
                  }
                  catch (Exception)
                  {
                      return false;
                  }
              }
    
              /// <summary>
              /// 从ftp服务器上获得文件夹列表
              /// </summary>
              /// <param name="RequedstPath">服务器下的相对路径</param>
              /// <returns></returns>
              public  List<string> GetDirctory(string RequedstPath)
              {
                  List<string> strs = new List<string>();
                  try
                  {
                      string uri = "ftp://" + strRemoteHost + ":" + strRemotePort.ToString() + "/" + RequedstPath;   //目标路径 path为服务器地址
                      FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                      // ftp用户名和密码
                      reqFTP.Credentials = new NetworkCredential(strRemoteUser, strRemotePass);
                      reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                      WebResponse response = reqFTP.GetResponse();
                      StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名
    
                      string line = reader.ReadLine();
                      while (line != null)
                      {
                          if (line.Contains("<DIR>"))
                          {
                              string msg = line.Substring(line.LastIndexOf("<DIR>") + 5).Trim();
                              strs.Add(msg);
                          }
                          line = reader.ReadLine();
                      }
                      reader.Close();
                      response.Close();
                      return strs;
                  }
                  catch (Exception ex)
                  {
                      throw new IOException("获取目录出错:" + ex.Message);
                  }
                  return strs;
              }
    
              /// <summary>
              /// 判断目录是否存在
              /// </summary>
              /// <param name="pFtpServerIP"></param>
              /// <returns></returns>
              private  bool DirectoryIsExist(Uri pFtpServerIP, string strRemoteUser, string strRemotePass)
              {
                  string[] value = GetFileList(pFtpServerIP, strRemoteUser, strRemotePass);
                  if (value == null)
                  {
                      return false;
                  }
                  else
                  {
                      return true;
                  }
              }
    
              /// <summary>
              ///  获取该目录以及目录下所有的文件
              /// </summary>
              /// <param name="pFtpServerIP"></param>
              /// <returns></returns>
              public  string[] GetFileList(Uri pFtpServerIP, string strRemoteUser, string strRemotePass)
              {
                  StringBuilder result = new StringBuilder();
                  try
                  {
                      FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(pFtpServerIP);
                      reqFTP.UseBinary = true;
                      reqFTP.Credentials = new NetworkCredential(strRemoteUser, strRemotePass);
                      reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    
                      WebResponse response = reqFTP.GetResponse();
                      StreamReader reader = new StreamReader(response.GetResponseStream());
                      string line = reader.ReadLine();
                      if (string.IsNullOrEmpty(line))
                      {
                          reader.Close();
                          response.Close();
                          return null;
                      }
                      else
                      {
                          while (line != null)
                          {
                              result.Append(line);
                              result.Append("
    ");
                              line = reader.ReadLine();
                          }
                          reader.Close();
                          response.Close();
                          return result.ToString().Split('
    ');
                      }
                  }
                  catch
                  {
                      return null;
                  }
              }
    
    
               /// <summary>
               /// 改变目录
               /// </summary>
               /// <param name="strDirName">新的工作目录名</param>
               public void ChDir(string strDirName)
               {
                   if (strDirName.Equals(".") || strDirName.Equals(""))
                   {
                       return;
                   }
                   if (!bConnected)
                   {
                       Connect();
                   }
                   SendCommand("CWD " + strDirName);
                   if (iReplyCode != 250)
                   {
                       throw new IOException(strReply.Substring(4));
                   }
                   this.strRemotePath = strDirName;
               }
    
               #endregion
    
               /// <summary>
               /// 将一行应答字符串记录在strReply和strMsg
               /// 应答码记录在iReplyCode
               /// </summary>
               private void ReadReply()
               {
                   strMsg = "";
                   strReply = ReadLine();
                   iReplyCode = Int32.Parse(strReply.Substring(0, 3));
               }
    
               /// <summary>
               /// 建立进行数据连接的socket
               /// </summary>
               /// <returns>数据连接socket</returns>
               private Socket CreateDataSocket()
               {
                   SendCommand("PASV");
                   if (iReplyCode != 227)
                   {
                       throw new IOException(strReply.Substring(4));
                   }
                   int index1 = strReply.IndexOf('(');
                   int index2 = strReply.IndexOf(')');
                   string ipData =
                    strReply.Substring(index1 + 1, index2 - index1 - 1);
                   int[] parts = new int[6];
                   int len = ipData.Length;
                   int partCount = 0;
                   string buf = "";
                   for (int i = 0; i < len && partCount <= 6; i++)
                   {
                       char ch = Char.Parse(ipData.Substring(i, 1));
                       if (Char.IsDigit(ch))
                           buf += ch;
                       else if (ch != ',')
                       {
                           throw new IOException("Malformed PASV strReply: " +
                            strReply);
                       }
                       if (ch == ',' || i + 1 == len)
                       {
                           try
                           {
                               parts[partCount++] = Int32.Parse(buf);
                               buf = "";
                           }
                           catch (Exception)
                           {
                               throw new IOException("Malformed PASV strReply: " +
                                strReply);
                           }
                       }
                   }
                   string ipAddress = parts[0] + "." + parts[1] + "." +
                    parts[2] + "." + parts[3];
                   int port = (parts[4] << 8) + parts[5];
                   Socket s = new
                    Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                   IPEndPoint ep = new
                    IPEndPoint(IPAddress.Parse(ipAddress), port);
                   try
                   {
                       s.Connect(ep);
                   }
                   catch (Exception)
                   {
                       throw new IOException("Can't connect to remote server");
                   }
                   return s;
               }
    
    
               /// <summary>
               /// 关闭socket连接(用于登录以前)
               /// </summary>
               private void CloseSocketConnect()
               {
                   if (socketControl != null)
                   {
                       socketControl.Close();
                       socketControl = null;
                   }
                   bConnected = false;
               }
    
               /// <summary>
               /// 读取Socket返回的所有字符串
               /// </summary>
               /// <returns>包含应答码的字符串行</returns>
               private string ReadLine()
               {
                   while (true)
                   {
                       int iBytes = socketControl.Receive(buffer, buffer.Length, 0);
                       strMsg += ASCII.GetString(buffer, 0, iBytes);
                       if (iBytes < buffer.Length)
                       {
                           break;
                       }
                   }
                   char[] seperator = { '
    ' };
                   string[] mess = strMsg.Split(seperator);
                   if (strMsg.Length > 2)
                   {
                       strMsg = mess[mess.Length - 2];
                       //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,
                       //但也会分配为空字符串给后面(也是最后一个)字符串数组,
                       //所以最后一个mess是没用的空字符串
                       //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格
                   }
                   else
                   {
                       strMsg = mess[0];
                   }
                   if (!strMsg.Substring(3, 1).Equals(" "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
                   {
                       return ReadLine();
                   }
                   return strMsg;
               }
    
    
               /// <summary>
               /// 发送命令并获取应答码和最后一行应答字符串
               /// </summary>
               /// <param name="strCommand">命令</param>
               private void SendCommand(string strCommand)
               {
                   Byte[] cmdBytes = ASCII.GetBytes((strCommand + "
    ").ToCharArray());
                   socketControl.Send(cmdBytes, cmdBytes.Length, 0);
                   ReadReply();
               }
    
              #endregion
        }
    }

    作者:Joe.Fan
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    十进制数转换
    桶排序
    快速排序
    单词倒排
    (c++) string b; cin>>b; int i=strlen(b); 报错的原因。
    n的阶乘(1<n<10000)(结果超大……)
    2020软件工程最后一次作业
    2020软件工程第四次作业
    2020软件工程第三次作业
    2020软件工程第二次作业
  • 原文地址:https://www.cnblogs.com/fanxingthink/p/4176145.html
Copyright © 2020-2023  润新知