首页 > 开发 > 综合 > 正文

FTP网站文件到本地的C#代码

2024-07-21 02:25:58
字体:
来源:转载
供稿:网友

using system.net;
using system.io;
using system.text;
using system.net.sockets;

调用示例:

//调用开始:
   ftpclient ftpniugames=new ftpclient();   
   ftpniugames.remotehost=textbox3.text;
   ftpniugames.remoteuser=textbox5.text;
   ftpniugames.remotepass=textbox6.text;
   ftpniugames.remotepath=txtftpdir.text;;
   ftpniugames.remoteport=int.parse(textbox7.text);   
   ftpniugames.connect();
   textbox8.text="成功打开ftp连接";
   //ftpniugames.get("shniugames.mdb","c://");
   ftpniugames.get(strftpfile,strlocaldir);
   textbox8.text=textbox8.text + "/r/nftp文件:"+strftpdir+"文件到本地:" +strlocalfilepath+ "完成";
   ftpniugames.disconnect();
   textbox8.text=textbox8.text + "/r/n成功关闭ftp连接";

//调用完成

 

 /// <summary>
 /// ftp client
 /// </summary>
 public class ftpclient
 {
  #region 构造函数
  /// <summary>
  /// 缺省构造函数
  /// </summary>
  public ftpclient()
  {
   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 ftpclient( string remotehost, string remotepath, string remoteuser, string remotepass, int remoteport )
  {
   strremotehost  = remotehost;
   strremotepath  = remotepath;
   strremoteuser  = remoteuser;
   strremotepass  = remotepass;
   strremoteport  = remoteport;
   connect();
  }
  #endregion

  #region 登陆
  /// <summary>
  /// ftp服务器ip地址
  /// </summary>
  private string strremotehost;
  public string remotehost
  {
   get
   {
    return strremotehost;
   }
   set
   {
    strremotehost = value;
   }
  }
  /// <summary>
  /// ftp服务器端口
  /// </summary>
  private int strremoteport;
  public int remoteport
  {
   get
   {
    return strremoteport;
   }
   set
   {
    strremoteport = value;
   }
  }
  /// <summary>
  /// 当前服务器目录
  /// </summary>
  private string strremotepath;
  public string remotepath
  {
   get
   {
    return strremotepath;
   }
   set
   {
    strremotepath = value;
   }
  }
  /// <summary>
  /// 登录用户账号
  /// </summary>
  private string strremoteuser;
  public string remoteuser
  {
   set
   {
    strremoteuser = value;
   }
  }
  /// <summary>
  /// 用户登录密码
  /// </summary>
  private string strremotepass;
  public string remotepass
  {
   set
   {
    strremotepass = value;
   }
  }

  /// <summary>
  /// 是否登录
  /// </summary>
  private boolean bconnected;
  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>
  /// 传输模式:二进制类型、ascii类型
  /// </summary>
  public enum transfertype {binary,ascii};

  /// <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 = {'/n'};
   string[] strsfilelist = strmsg.split(seperator);
   socketdata.close();//数据socket关闭时也会有返回码
   if(ireplycode != 226)
   {
    readreply();
    if(ireplycode != 226)
    {
     throw new ioexception(strreply.substring(4));
    }
   }
   return strsfilelist;
  }
   

  /// <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="str c#下载文件时候弹出选择文件夹保存目录的代码c#下载文件时候弹出选择文件夹保存目录的代码 c#根据计算机名获取对应ip地址c#根据计算机名获取对应ip地址 c#获取网络邻居所有工作组和机器名称c#获取网络邻居所有工作组和机器名称 c#列表所有iis站点以及相关站点属性c#列表所有iis站点以及相关站点属性 c#读取iis中的站点相关属性代码c#读取iis中的站点相关属性代码 c#新建站点,删除站点函数代码c#新建站点,删除站点函数代码 c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数 c#根据网址获取域名,目录名,文件名函数c#根据网址获取域名,目录名,文件名函数 c#获取本机电脑相关信息c#获取本机电脑相关信息 ftp网站文件到本地的c#代码ftp网站文件到本地的c#代码 c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码 c#中调用对应的应用程打开文件序的代码c#中调用对应的应用程打开文件序的代码 数据表文件导出execel文件-本地测试成功数据表文件导出execel文件-本地测试成功 c#新保存文件时候用到按日期时间命名的代码c#新保存文件时候用到按日期时间命名的代码 c#根据网址抓取目录和文件名的两个函数c#根据网址抓取目录和文件名的两个函数 c#下载文件函数c#下载文件函数 c#用线程传参下载文件的代码c#用线程传参下载文件的代码 c#使用线程下载文件的控制技巧和缺陷c#使用线程下载文件的控制技巧和缺陷 asp.net中安装使用owc组件生成execel步骤asp.net中安装使用owc组件生成execel步骤 批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码name">新文件名</param>
  public void rename(string stroldfilename,string str c#下载文件时候弹出选择文件夹保存目录的代码c#下载文件时候弹出选择文件夹保存目录的代码 c#根据计算机名获取对应ip地址c#根据计算机名获取对应ip地址 c#获取网络邻居所有工作组和机器名称c#获取网络邻居所有工作组和机器名称 c#列表所有iis站点以及相关站点属性c#列表所有iis站点以及相关站点属性 c#读取iis中的站点相关属性代码c#读取iis中的站点相关属性代码 c#新建站点,删除站点函数代码c#新建站点,删除站点函数代码 c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数 c#根据网址获取域名,目录名,文件名函数c#根据网址获取域名,目录名,文件名函数 c#获取本机电脑相关信息c#获取本机电脑相关信息 ftp网站文件到本地的c#代码ftp网站文件到本地的c#代码 c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码 c#中调用对应的应用程打开文件序的代码c#中调用对应的应用程打开文件序的代码 数据表文件导出execel文件-本地测试成功数据表文件导出execel文件-本地测试成功 c#新保存文件时候用到按日期时间命名的代码c#新保存文件时候用到按日期时间命名的代码 c#根据网址抓取目录和文件名的两个函数c#根据网址抓取目录和文件名的两个函数 c#下载文件函数c#下载文件函数 c#用线程传参下载文件的代码c#用线程传参下载文件的代码 c#使用线程下载文件的控制技巧和缺陷c#使用线程下载文件的控制技巧和缺陷 asp.net中安装使用owc组件生成execel步骤asp.net中安装使用owc组件生成execel步骤 批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码name)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand("rnfr "+stroldfilename);
   if(ireplycode != 350)
   {
    throw new ioexception(strreply.substring(4));
   }
   //  如果新文件名与原有文件重名,将覆盖原有文件
   sendcommand("rnto "+str c#下载文件时候弹出选择文件夹保存目录的代码c#下载文件时候弹出选择文件夹保存目录的代码 c#根据计算机名获取对应ip地址c#根据计算机名获取对应ip地址 c#获取网络邻居所有工作组和机器名称c#获取网络邻居所有工作组和机器名称 c#列表所有iis站点以及相关站点属性c#列表所有iis站点以及相关站点属性 c#读取iis中的站点相关属性代码c#读取iis中的站点相关属性代码 c#新建站点,删除站点函数代码c#新建站点,删除站点函数代码 c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数c#下在图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数 c#根据网址获取域名,目录名,文件名函数c#根据网址获取域名,目录名,文件名函数 c#获取本机电脑相关信息c#获取本机电脑相关信息 ftp网站文件到本地的c#代码ftp网站文件到本地的c#代码 c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码c#保存文件时候的弹出选择要保存的文件夹带新建文件夹效果的类代码 c#中调用对应的应用程打开文件序的代码c#中调用对应的应用程打开文件序的代码 数据表文件导出execel文件-本地测试成功数据表文件导出execel文件-本地测试成功 c#新保存文件时候用到按日期时间命名的代码c#新保存文件时候用到按日期时间命名的代码 c#根据网址抓取目录和文件名的两个函数c#根据网址抓取目录和文件名的两个函数 c#下载文件函数c#下载文件函数 c#用线程传参下载文件的代码c#用线程传参下载文件的代码 c#使用线程下载文件的控制技巧和缺陷c#使用线程下载文件的控制技巧和缺陷 asp.net中安装使用owc组件生成execel步骤asp.net中安装使用owc组件生成execel步骤 批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码批量抓取网页代码中的http和邮件地址,io,正则表达式,抓网页源码name);
   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();
   }
   string[] strfiles = dir(strfilenamemask);
   foreach(string strfile in strfiles)
   {
    if(!strfile.equals(""))//一般来说strfiles的最后一个元素可能是空字符串
    {
     get(strfile,strfolder,strfile);
    }
   }
  }
   

  /// <summary>
  /// 下载一个文件
  /// </summary>
  /// <param name="strremotefilename">要下载的文件名</param>
  /// <param name="strfolder">本地目录(不得以/结束)</param>
  /// <param name="strlocalfilename">保存在本地时的文件名</param>
  public void get(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 " + 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>
  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

  #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>
  /// 接收和发送数据的缓冲区
  /// </summary>
  private static int block_size = 512;
  byte[] buffer = new byte[block_size];
  /// <summary>
  /// 编码方式
  /// </summary>
  encoding ascii = encoding.ascii;
  #endregion

  #region 内部函数
  /// <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 = {'/n'};
   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 =
    encoding.ascii.getbytes((strcommand+"/r/n").tochararray());
   socketcontrol.send(cmdbytes, cmdbytes.length, 0);
   readreply();
  }

  #endregion
 }

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表