FTP上传文件示例

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介:

 首先,你需要一个测试环境,我在自己的机器上搭建了一个FTP Server,搭建Server有一些比较优秀的软件,例如:Crob FTP Server,不过这是一个收费软件,虽然提供试用版,但要在公网上使用的话,还是买个注册号吧!

    下载地址: Crob FTP Server V3.7.0 Build 196 简体中文版 http://www.skycn.com/soft/11246.html

    中文软件,大家都是学技术的,怎么搭建我就不说了。

    相当傻瓜式的,上传代码只有寥寥几行:

  1. FTPClient fc = new FTPClient();
  2. fc.RemoteHost = "10.6.133.145"// 这里只能用IP,而不能用机器名。当然,你可以利用工具类通过机器名获取到IP地址
  3. fc.RemotePath = "/u01/upload";  // FTP服务器的虚拟目录
  4. fc.RemotePort = 21;
  5. fc.RemoteUser = "admin";
  6. fc.RemotePass = "123";
  7. fc.Connect();
  8. fc.Put("c:/1.txt");
  9. fc.DisConnect();

    这里要注意的是,虚拟目录/u01/upload对应的路径需要有写文件操作的权限,你可以在属性中配置账号的写权限(我直接共享了该文件夹,并允许everyone账号完全控制)。

    这里提供FTPClient.cs的源码,来源一时半会儿找不到了:

  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Text;
  5. using System.IO;
  6. namespace TimerServer
  7. {
  8.     /// <summary>
  9.     /// FTPClient 的摘要说明。
  10.     /// </summary>
  11.     public class FTPClient
  12.     {
  13.         #region 构造函数
  14.         /**//// <summary>
  15.         /// 缺省构造函数
  16.         /// </summary>
  17.         public FTPClient()
  18.         {
  19.             strRemoteHost  = "";
  20.             strRemotePath  = "";
  21.             strRemoteUser  = "";
  22.             strRemotePass  = "";
  23.             strRemotePort  = 21;
  24.             bConnected
  25.                 = false;
  26.         }
  27.     /**//// <summary>
  28.     /// 构造函数
  29.     /// </summary>
  30.     /// <param name="remoteHost"></param>
  31.     /// <param name="remotePath"></param>
  32.     /// <param name="remoteUser"></param>
  33.     /// <param name="remotePass"></param>
  34.     /// <param name="remotePort"></param>
  35.     public FTPClient( string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort )
  36.     {
  37.         strRemoteHost  = remoteHost;
  38.         strRemotePath  = remotePath;
  39.         strRemoteUser  = remoteUser;
  40.         strRemotePass  = remotePass;
  41.         strRemotePort  = remotePort;
  42.         Connect();
  43.     }
  44.     #endregion
  45.     #region 登陆
  46.     /**//// <summary>
  47.     /// FTP服务器IP地址
  48.     /// </summary>
  49.     private string strRemoteHost;
  50.     public string RemoteHost
  51.     {
  52.         get
  53.         {
  54.             return strRemoteHost;
  55.         }
  56.         set
  57.         {
  58.             strRemoteHost = value;
  59.         }
  60.     }
  61.     /**//// <summary>
  62.     /// FTP服务器端口
  63.     /// </summary>
  64.     private int strRemotePort;
  65.     public int RemotePort
  66.     {
  67.         get
  68.         {
  69.             return strRemotePort;
  70.         }
  71.         set
  72.         {
  73.             strRemotePort = value;
  74.         }
  75.     }
  76.     /**//// <summary>
  77.     /// 当前服务器目录
  78.     /// </summary>
  79.     private string strRemotePath;
  80.     public string RemotePath
  81.     {
  82.         get
  83.         {
  84.             return strRemotePath;
  85.         }
  86.         set
  87.         {
  88.             strRemotePath = value;
  89.         }
  90.     }
  91.     /**//// <summary>
  92.     /// 登录用户账号
  93.     /// </summary>
  94.     private string strRemoteUser;
  95.     public string RemoteUser
  96.     {
  97.         set
  98.         {
  99.             strRemoteUser = value;
  100.         }
  101.     }
  102.     /**//// <summary>
  103.     /// 用户登录密码
  104.     /// </summary>
  105.     private string strRemotePass;
  106.     public string RemotePass
  107.     {
  108.         set
  109.         {
  110.             strRemotePass = value;
  111.         }
  112.     }
  113.     /**//// <summary>
  114.     /// 是否登录
  115.     /// </summary>
  116.     private Boolean bConnected;
  117.     public bool Connected
  118.     {
  119.         get
  120.         {
  121.             return bConnected;
  122.         }
  123.     }
  124.     #endregion
  125.     #region 链接
  126.     /**//// <summary>
  127.     /// 建立连接 
  128.     /// </summary>
  129.     public void Connect()
  130.     {
  131.         socketControl = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  132.         IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort);
  133.         // 链接
  134.         try
  135.         {
  136.             socketControl.Connect(ep);
  137.         }
  138.         catch(Exception)
  139.         {
  140.             throw new IOException("Couldn't connect to remote server");
  141.         }
  142.     // 获取应答码
  143.     ReadReply();
  144.     if(iReplyCode != 220)
  145.     {
  146.         DisConnect();
  147.         throw new IOException(strReply.Substring(4));
  148.     }
  149.     // 登陆
  150.     SendCommand("USER "+strRemoteUser);
  151.     if( !(iReplyCode == 331 || iReplyCode == 230) )
  152.     {
  153.         CloseSocketConnect();//关闭连接
  154.         throw new IOException(strReply.Substring(4));
  155.     }
  156.     if( iReplyCode != 230 )
  157.     {
  158.         SendCommand("PASS "+strRemotePass);
  159.         if( !(iReplyCode == 230 || iReplyCode == 202) )
  160.         {
  161.             CloseSocketConnect();//关闭连接
  162.             throw new IOException(strReply.Substring(4));
  163.         }
  164.     }
  165.     bConnected = true;
  166.     // 切换到目录
  167.     ChDir(strRemotePath);
  168.     }
  169.     
  170.     /**//// <summary>
  171.     /// 关闭连接
  172.     /// </summary>
  173.     public void DisConnect()
  174.     {
  175.         if( socketControl != null )
  176.         {
  177.             SendCommand("QUIT");
  178.         }
  179.         CloseSocketConnect();
  180.     }
  181.     #endregion
  182.     #region 传输模式
  183.     /**//// <summary>
  184.     /// 传输模式:二进制类型、ASCII类型
  185.     /// </summary>
  186.     public enum TransferType {Binary,ASCII};
  187.     /**//// <summary>
  188.     /// 设置传输模式
  189.     /// </summary>
  190.     /// <param name="ttType">传输模式</param>
  191.     public void SetTransferType(TransferType ttType)
  192.     {
  193.         if(ttType == TransferType.Binary)
  194.         {
  195.             SendCommand("TYPE I");//binary类型传输
  196.         }
  197.         else
  198.         {
  199.             SendCommand("TYPE A");//ASCII类型传输
  200.         }
  201.         if (iReplyCode != 200)
  202.         {
  203.             throw new IOException(strReply.Substring(4));
  204.         }
  205.         else
  206.         {
  207.             trType = ttType;
  208.         }
  209.     }
  210.     /**//// <summary>
  211.     /// 获得传输模式
  212.     /// </summary>
  213.     /// <returns>传输模式</returns>
  214.     public TransferType GetTransferType()
  215.     {
  216.         return trType;
  217.     }
  218.     
  219.         #endregion
  220.     #region 文件操作
  221.     /**//// <summary>
  222.     /// 获得文件列表
  223.     /// </summary>
  224.     /// <param name="strMask">文件名的匹配字符串</param>
  225.     /// <returns></returns>
  226.     public string[] Dir(string strMask)
  227.     {
  228.         // 建立链接
  229.         if(!bConnected)
  230.         {
  231.             Connect();
  232.         }
  233.     //建立进行数据连接的socket
  234.     Socket socketData = CreateDataSocket();
  235.     //传送命令
  236.     SendCommand("NLST " + strMask);
  237.     //分析应答代码
  238.     if(!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226))
  239.     {
  240.         throw new IOException(strReply.Substring(4));
  241.     }
  242.     //获得结果
  243.     strMsg = "";
  244.     while(true)
  245.     {
  246.         int iBytes = socketData.Receive(buffer, buffer.Length, 0);
  247.         strMsg += ASCII.GetString(buffer, 0, iBytes);
  248.         if(iBytes < buffer.Length)
  249.         {
  250.             break;
  251.         }
  252.     }
  253.     char[] seperator = {'/n'};
  254.     string[] strsFileList = strMsg.Split(seperator);
  255.     socketData.Close();//数据socket关闭时也会有返回码
  256.     if(iReplyCode != 226)
  257.     {
  258.         ReadReply();
  259.         if(iReplyCode != 226)
  260.         {
  261.             throw new IOException(strReply.Substring(4));
  262.         }
  263.     }
  264.     return strsFileList;
  265.     }
  266.     
  267.     /**//// <summary>
  268.     /// 获取文件大小
  269.     /// </summary>
  270.     /// <param name="strFileName">文件名</param>
  271.     /// <returns>文件大小</returns>
  272.     private long GetFileSize(string strFileName)
  273.     {
  274.         if(!bConnected)
  275.         {
  276.             Connect();
  277.         }
  278.         SendCommand("SIZE " + Path.GetFileName(strFileName));
  279.         long lSize=0;
  280.         if(iReplyCode == 213)
  281.         {
  282.             lSize = Int64.Parse(strReply.Substring(4));
  283.         }
  284.         else
  285.         {
  286.             throw new IOException(strReply.Substring(4));
  287.         }
  288.         return lSize;
  289.     }
  290.     /**//// <summary>
  291.     /// 删除
  292.     /// </summary>
  293.     /// <param name="strFileName">待删除文件名</param>
  294.     public void Delete(string strFileName)
  295.     {
  296.         if(!bConnected)
  297.         {
  298.             Connect();
  299.         }
  300.         SendCommand("DELE "+strFileName);
  301.         if(iReplyCode != 250)
  302.         {
  303.             throw new IOException(strReply.Substring(4));
  304.         }
  305.     }
  306.     
  307.     /**//// <summary>
  308.     /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
  309.     /// </summary>
  310.     /// <param name="strOldFileName">旧文件名</param>
  311.     /// <param name="strNewFileName">新文件名</param>
  312.     public void Rename(string strOldFileName,string strNewFileName)
  313.     {
  314.         if(!bConnected)
  315.         {
  316.             Connect();
  317.         }
  318.         SendCommand("RNFR "+strOldFileName);
  319.         if(iReplyCode != 350)
  320.         {
  321.             throw new IOException(strReply.Substring(4));
  322.         }
  323.         //  如果新文件名与原有文件重名,将覆盖原有文件
  324.         SendCommand("RNTO "+strNewFileName);
  325.         if(iReplyCode != 250)
  326.         {
  327.             throw new IOException(strReply.Substring(4));
  328.         }
  329.     }
  330.     #endregion
  331.     #region 上传和下载
  332.     /**//// <summary>
  333.     /// 下载一批文件
  334.     /// </summary>
  335.     /// <param name="strFileNameMask">文件名的匹配字符串</param>
  336.     /// <param name="strFolder">本地目录(不得以/结束)</param>
  337.     public void Get(string strFileNameMask,string strFolder)
  338.     {
  339.         if(!bConnected)
  340.         {
  341.             Connect();
  342.         }
  343.         string[] strFiles = Dir(strFileNameMask);
  344.         foreach(string strFile in strFiles)
  345.         {
  346.             if(!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串
  347.             {
  348.                 Get(strFile,strFolder,strFile);
  349.             }
  350.         }
  351.     }
  352.     
  353.     /**//// <summary>
  354.     /// 下载一个文件
  355.     /// </summary>
  356.     /// <param name="strRemoteFileName">要下载的文件名</param>
  357.     /// <param name="strFolder">本地目录(不得以/结束)</param>
  358.     /// <param name="strLocalFileName">保存在本地时的文件名</param>
  359.     public void Get(string strRemoteFileName,string strFolder,string strLocalFileName)
  360.     {
  361.         if(!bConnected)
  362.         {
  363.             Connect();
  364.         }
  365.         SetTransferType(TransferType.Binary);
  366.         if (strLocalFileName.Equals(""))
  367.         {
  368.             strLocalFileName = strRemoteFileName;
  369.         }
  370.         if(!File.Exists(strFolder + "//" +strLocalFileName))
  371.         {
  372.             Stream st = File.Create(strFolder + "//" +strLocalFileName);
  373.             st.Close();
  374.         }
  375.         FileStream output = new 
  376.             FileStream(strFolder + "//" + strLocalFileName,FileMode.Create);
  377.         Socket socketData = CreateDataSocket();
  378.         SendCommand("RETR " + strRemoteFileName);
  379.         if(!(iReplyCode == 150 || iReplyCode == 125
  380.             || iReplyCode == 226 || iReplyCode == 250))
  381.         {
  382.             throw new IOException(strReply.Substring(4));
  383.         }
  384.         while(true)
  385.         {
  386.             int iBytes = socketData.Receive(buffer, buffer.Length, 0);
  387.             output.Write(buffer,0,iBytes);
  388.             if(iBytes <= 0)
  389.             {
  390.                 break;
  391.             }
  392.         }
  393.         output.Close();
  394.         if (socketData.Connected)
  395.         {
  396.             socketData.Close();
  397.         }
  398.         if(!(iReplyCode == 226 || iReplyCode == 250))
  399.         {
  400.             ReadReply();
  401.             if(!(iReplyCode == 226 || iReplyCode == 250))
  402.             {
  403.                 throw new IOException(strReply.Substring(4));
  404.             }
  405.         }
  406.     }
  407.     
  408.     /**//// <summary>
  409.     /// 上传一批文件
  410.     /// </summary>
  411.     /// <param name="strFolder">本地目录(不得以/结束)</param>
  412.     /// <param name="strFileNameMask">文件名匹配字符(可以包含*和?)</param>
  413.     public void Put(string strFolder,string strFileNameMask)
  414.     {
  415.         string[] strFiles = Directory.GetFiles(strFolder,strFileNameMask);
  416.         foreach(string strFile in strFiles)
  417.         {
  418.             //strFile是完整的文件名(包含路径)
  419.             Put(strFile);
  420.         }
  421.     }
  422.     
  423.     /**//// <summary>
  424.     /// 上传一个文件
  425.     /// </summary>
  426.     /// <param name="strFileName">本地文件名</param>
  427.     public void Put(string strFileName)
  428.     {
  429.         if(!bConnected)
  430.         {
  431.             Connect();
  432.         }
  433.         Socket socketData = CreateDataSocket();
  434.         SendCommand("STOR "+Path.GetFileName(strFileName));
  435.         if( !(iReplyCode == 125 || iReplyCode == 150) )
  436.         {
  437.             throw new IOException(strReply.Substring(4));
  438.         }
  439.         FileStream input = new 
  440.             FileStream(strFileName,FileMode.Open);
  441.         int iBytes = 0;
  442.         while ((iBytes = input.Read(buffer,0,buffer.Length)) > 0)
  443.         {
  444.             socketData.Send(buffer, iBytes, 0);
  445.         }
  446.         input.Close();
  447.         if (socketData.Connected)
  448.         {
  449.             socketData.Close();
  450.         }
  451.         if(!(iReplyCode == 226 || iReplyCode == 250))
  452.         {
  453.             ReadReply();
  454.             if(!(iReplyCode == 226 || iReplyCode == 250))
  455.             {
  456.                 throw new IOException(strReply.Substring(4));
  457.             }
  458.         }
  459.     }
  460.     
  461.         #endregion
  462.     #region 目录操作
  463.     /**//// <summary>
  464.     /// 创建目录
  465.     /// </summary>
  466.     /// <param name="strDirName">目录名</param>
  467.     public void MkDir(string strDirName)
  468.     {
  469.         if(!bConnected)
  470.         {
  471.             Connect();
  472.         }
  473.         SendCommand("MKD "+strDirName);
  474.         if(iReplyCode != 257)
  475.         {
  476.             throw new IOException(strReply.Substring(4));
  477.         }
  478.     }
  479.     
  480.     /**//// <summary>
  481.     /// 删除目录
  482.     /// </summary>
  483.     /// <param name="strDirName">目录名</param>
  484.     public void RmDir(string strDirName)
  485.     {
  486.         if(!bConnected)
  487.         {
  488.             Connect();
  489.         }
  490.         SendCommand("RMD "+strDirName);
  491.         if(iReplyCode != 250)
  492.         {
  493.             throw new IOException(strReply.Substring(4));
  494.         }
  495.     }
  496.     
  497.     /**//// <summary>
  498.     /// 改变目录
  499.     /// </summary>
  500.     /// <param name="strDirName">新的工作目录名</param>
  501.     public void ChDir(string strDirName)
  502.     {
  503.         if(strDirName.Equals(".") || strDirName.Equals(""))
  504.         {
  505.             return;
  506.         }
  507.         if(!bConnected)
  508.         {
  509.             Connect();
  510.         }
  511.         SendCommand("CWD "+strDirName);
  512.         if(iReplyCode != 250)
  513.         {
  514.             throw new IOException(strReply.Substring(4));
  515.         }
  516.         this.strRemotePath = strDirName;
  517.     }
  518.     
  519.         #endregion
  520.     #region 内部变量
  521.     /**//// <summary>
  522.     /// 服务器返回的应答信息(包含应答码)
  523.     /// </summary>
  524.     private string strMsg;
  525.     /**//// <summary>
  526.     /// 服务器返回的应答信息(包含应答码)
  527.     /// </summary>
  528.     private string strReply;
  529.     /**//// <summary>
  530.     /// 服务器返回的应答码
  531.     /// </summary>
  532.     private int iReplyCode;
  533.     /**//// <summary>
  534.     /// 进行控制连接的socket
  535.     /// </summary>
  536.     private Socket socketControl;
  537.     /**//// <summary>
  538.     /// 传输模式
  539.     /// </summary>
  540.     private TransferType trType;
  541.     /**//// <summary>
  542.     /// 接收和发送数据的缓冲区
  543.     /// </summary>
  544.     private static int BLOCK_SIZE = 512;
  545.     Byte[] buffer = new Byte[BLOCK_SIZE];
  546.     /**//// <summary>
  547.     /// 编码方式
  548.     /// </summary>
  549.     Encoding ASCII = Encoding.ASCII;
  550.     #endregion
  551.     #region 内部函数
  552.         /**//// <summary>
  553.         /// 将一行应答字符串记录在strReply和strMsg
  554.         /// 应答码记录在iReplyCode
  555.         /// </summary>
  556.         private void ReadReply()
  557.         {
  558.             strMsg = "";
  559.             strReply = ReadLine();
  560.             iReplyCode = Int32.Parse(strReply.Substring(0,3));
  561.         }
  562.     /**//// <summary>
  563.     /// 建立进行数据连接的socket
  564.     /// </summary>
  565.     /// <returns>数据连接socket</returns>
  566.     private Socket CreateDataSocket()
  567.     {
  568.         SendCommand("PASV");
  569.         if(iReplyCode != 227)
  570.         {
  571.             throw new IOException(strReply.Substring(4));
  572.         }
  573.         int index1 = strReply.IndexOf('(');
  574.         int index2 = strReply.IndexOf(')');
  575.         string ipData = 
  576.             strReply.Substring(index1+1,index2-index1-1);
  577.         int[] parts = new int[6];
  578.         int len = ipData.Length;
  579.         int partCount = 0;
  580.         string buf="";
  581.         for (int i = 0; i < len && partCount <= 6; i++)
  582.         {
  583.             char ch = Char.Parse(ipData.Substring(i,1));
  584.             if (Char.IsDigit(ch))
  585.                 buf+=ch;
  586.             else if (ch != ',')
  587.             {
  588.                 throw new IOException("Malformed PASV strReply: " + 
  589.                     strReply);
  590.             }
  591.             if (ch == ',' || i+1 == len)
  592.             {
  593.                 try
  594.                 {
  595.                     parts[partCount++] = Int32.Parse(buf);
  596.                     buf="";
  597.                 }
  598.                 catch (Exception)
  599.                 {
  600.                     throw new IOException("Malformed PASV strReply: " + 
  601.                         strReply);
  602.                 }
  603.             }
  604.         }
  605.         string ipAddress = parts[0] + "."+ parts[1]+ "." +
  606.             parts[2] + "." + parts[3];
  607.         int port = (parts[4] << 8) + parts[5];
  608.         Socket s = new 
  609.             Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  610.         IPEndPoint ep = new 
  611.             IPEndPoint(IPAddress.Parse(ipAddress), port);
  612.         try
  613.         {
  614.             s.Connect(ep);
  615.         }
  616.         catch(Exception)
  617.         {
  618.             throw new IOException("Can't connect to remote server");
  619.         }
  620.         return s;
  621.     }
  622.     /**//// <summary>
  623.     /// 关闭socket连接(用于登录以前)
  624.     /// </summary>
  625.     private void CloseSocketConnect()
  626.     {
  627.         if(socketControl!=null)
  628.         {
  629.             socketControl.Close();
  630.             socketControl = null;
  631.         }
  632.         bConnected = false;
  633.     }
  634.     /**//// <summary>
  635.     /// 读取Socket返回的所有字符串
  636.     /// </summary>
  637.     /// <returns>包含应答码的字符串行</returns>
  638.     private string ReadLine()
  639.     {
  640.         while(true)
  641.         {
  642.             int iBytes = socketControl.Receive(buffer, buffer.Length, 0);
  643.             strMsg += ASCII.GetString(buffer, 0, iBytes);
  644.             if(iBytes < buffer.Length)
  645.             {
  646.                 break;
  647.             }
  648.         }
  649.         char[] seperator = {'/n'};
  650.         string[] mess = strMsg.Split(seperator);
  651.         if(strMsg.Length > 2)
  652.         {
  653.             strMsg = mess[mess.Length-2];
  654.             //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,
  655.             //但也会分配为空字符串给后面(也是最后一个)字符串数组,
  656.             //所以最后一个mess是没用的空字符串
  657.             //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格
  658.         }
  659.         else
  660.         {
  661.             strMsg = mess[0];
  662.         }
  663.         if(!strMsg.Substring(3,1).Equals(" "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
  664.         {
  665.             return ReadLine();
  666.         }
  667.         return strMsg;
  668.     }
  669.     /**//// <summary>
  670.     /// 发送命令并获取应答码和最后一行应答字符串
  671.     /// </summary>
  672.     /// <param name="strCommand">命令</param>
  673.     private void SendCommand(String strCommand)
  674.     {
  675.         Byte[] cmdBytes = 
  676.             Encoding.ASCII.GetBytes((strCommand+"/r/n").ToCharArray());
  677.         socketControl.Send(cmdBytes, cmdBytes.Length, 0);
  678.         ReadReply();
  679.     }
  680.     #endregion
  681.     } 
  682. }

该工具类还提供一些文件操作,注释也比较丰富,再次向这个类的作者致敬。

-------------------------------------------------

这个类有一种无法处理的情况,如果FTP服务器使用SSL或者SSH2安全协议搭建的Secure FTP Server,就无法链接上了。在网上找到一个可行的办法,见文章:http://blog.csdn.net/venus0314/archive/2006/09/21/1262386.aspx

原理是利用psftp.exe工具来上传文件,上传过程和通讯协议都被隐藏了,通过流写DOS命令来文件的复制与粘贴的操作。我写过测试类,但没有成功,不过应该是一个可行的办法,正在想办法研究,如果有结果将会在博客中放出来。

psftp.exe比较难找,但还是找的到的。google吧!

 

-------------------------------------------------

Updated On 2008-10-21

FTPClient类中没有包含Append的功能,即将本地文件的内容追加到远程文件上的功能。这里,我放上来一个通过了测试的Append方法:

  1. /// <summary>
  2. /// 文件Append操作
  3. /// </summary>
  4. /// <param name="strFileName">被Append的本地文件名,要求与远程文件名一致</param>
  5. public void Append(string strFileName)
  6. {
  7.     if(!bConnected)
  8.         Connect();
  9.     Socket socketData = CreateDataSocket();
  10.     SetTransferType(TransferType.Binary);
  11.     SendCommand("APPE " + Path.GetFileName(strFileName));       
  12.     if( !(iReplyCode == 125 || iReplyCode == 150) )
  13.     {
  14.         throw new IOException(strReply.Substring(4));
  15.     }
  16.     FileStream input = new FileStream(strFileName,FileMode.Open);
  17.     int iBytes = 0;
  18.     while ((iBytes = input.Read(buffer,0,buffer.Length)) > 0)
  19.     {
  20.         socketData.Send(buffer, iBytes, 0);
  21.     }
  22.     input.Close();
  23.     if (socketData.Connected)
  24.     {
  25.         socketData.Close();
  26.     }
  27.     if(!(iReplyCode == 226 || iReplyCode == 250))
  28.     {
  29.         ReadReply();
  30.         if(!(iReplyCode == 226 || iReplyCode == 250))
  31.         {
  32.             throw new IOException(strReply.Substring(4));
  33.         }
  34.     }
  35. }

    这里没有提供指定FTP远程服务器上文件名的功能,要求你上传的本地文件名与远程数据库文件名一致。事实上,我做过指定远程文件名的尝试,即将命令该为“APPE local-file remote-file”的格式,但我发现,结果是,它把本地文件的内容传上去后,生成了一个文件名为local-file与remote-file拼接后的新文件,令人费解!!

目录
相关文章
|
6月前
|
安全 算法 网络协议
【Linux】文件服务FTP(File Transfer Protocol)
【Linux】文件服务FTP(File Transfer Protocol)
101 0
|
6月前
|
开发框架 Java 数据处理
多sheet页导出 + FTP上传文件实战
多sheet页导出 + FTP上传文件实战
|
11月前
|
网络协议 安全 Linux
小白带你学习文件共享服务器FTP和SAMBA的学习(二十二)
小白带你学习文件共享服务器FTP和SAMBA的学习(二十二)
169 0
文件复制到ftp服务器时发生错误,请检查是否有权限将文件放到该服务器上
文件复制到ftp服务器时发生错误,请检查是否有权限将文件放到该服务器上
5402 0
|
21天前
|
网络安全 Windows
Jetson 学习笔记(十五):FTP协议传输文件
本文介绍了如何使用WinSCP软件通过FTP协议在Windows和Jetson设备之间传输文件,并分享了一些操作经验和技巧。
21 0
Jetson 学习笔记(十五):FTP协议传输文件
|
3月前
|
Java
Java SpringBoot FTP 上传下载文件
Java SpringBoot FTP 上传下载文件
127 0
|
6月前
|
存储 Linux 文件存储
网络文件共享ftp
网络文件共享ftp
|
6月前
|
存储 Unix Linux
LabVIEW与实时目标之间的FTP文件
LabVIEW与实时目标之间的FTP文件
214 0
|
6月前
|
Java
java上传、下载、预览、删除ftp服务器上的文件
java上传、下载、预览、删除ftp服务器上的文件
Java——通过Java代码从ftp服务器下载文件
Java——通过Java代码从ftp服务器下载文件