1、ftpclient 类

  public class FTPClient:IDisposable{public static object _obj = new object();#region 构造函数/// <summary>/// 缺省构造函数/// </summary>public FTPClient(){_strRemoteHost = "";_strRemotePath = "";_strRemoteUser = "";_strRemotePass = "";_strRemotePort = 21;_bConnected = false;}/// <summary>/// 构造函数/// </summary>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 字段private int _strRemotePort;private Boolean _bConnected;private string _strRemoteHost;private string _strRemotePass;private string _strRemoteUser;private string _strRemotePath;/// <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;/// <summary>/// 编码方式/// </summary>Encoding _ASCII = Encoding.UTF8;/// <summary>/// 字节数组/// </summary>Byte[] _buffer = new Byte[_BLOCK_SIZE];#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 RemotePwd{set{_strRemotePass = value;}}/// <summary>/// 是否登录/// </summary>public bool Connected{get{return _bConnected;}}#endregion#region 链接/// <summary>/// 建立连接 /// </summary>public void Connect(){lock (_obj){_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("不能连接ftp服务器");}}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>public string[] Dir(string strMask){if (!_bConnected){Connect();}Socket socketData = CreateDataSocket();SendCommand("NLST " + strMask);if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226)){throw new IOException(_strReply.Substring(4));}_strMsg = "";Thread.Sleep(2000);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;}public void newPutByGuid(string strFileName, string strGuid){if (!_bConnected){Connect();}string str = strFileName.Substring(0, strFileName.LastIndexOf("\\"));string strTypeName = strFileName.Substring(strFileName.LastIndexOf("."));strGuid = str + "\\" + strGuid;Socket socketData = CreateDataSocket();SendCommand("STOR " + Path.GetFileName(strGuid));if (!(_iReplyCode == 125 || _iReplyCode == 150)){throw new IOException(_strReply.Substring(4));}FileStream input = new FileStream(strGuid, FileMode.Open);input.Flush();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));}}}/// <summary>/// 获取文件大小/// 当文件在ftp服务器上不存在时,报异常/// </summary>/// <param name="strFileName">文件名</param>/// <returns>文件大小</returns>public 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>/// <returns>文件大小</returns>public string GetFileInfo(string strFileName){if (!_bConnected){Connect();}Socket socketData = CreateDataSocket();SendCommand("LIST " + strFileName);string strResult = "";if (!(_iReplyCode == 150 || _iReplyCode == 125|| _iReplyCode == 226 || _iReplyCode == 250)){throw new IOException(_strReply.Substring(4));}byte[] b = new byte[512];MemoryStream ms = new MemoryStream();while (true){int iBytes = socketData.Receive(b, b.Length, 0);ms.Write(b, 0, iBytes);if (iBytes <= 0){break;}}byte[] bt = ms.GetBuffer();strResult = System.Text.Encoding.ASCII.GetString(bt);ms.Close();return strResult;}/// <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();}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=""){Socket socketData = CreateDataSocket();try{if (!_bConnected){Connect();}SetTransferType(TransferType.Binary);strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName);SendCommand("RETR " + strRemoteFileName);if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250)){throw new IOException(_strReply.Substring(4));}FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);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));}}}catch{socketData.Close();socketData = null;_socketControl.Close();_bConnected = false;_socketControl = null;}}/// <summary>/// 下载一个文件,支持断点下载/// </summary>/// <param name="strRemoteFileName"></param>/// <param name="strFolder"></param>/// <param name="strLocalFileName"></param>/// <param name="size"></param>public void GetBrokenFile(string strRemoteFileName, string strFolder, string strLocalFileName=""){if (!_bConnected){Connect();}SetTransferType(TransferType.Binary);strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName);long localFileSize = 0;var localfileWithFullname = strFolder + "//" + strLocalFileName;if (File.Exists(localfileWithFullname)){FileInfo fInfo = new FileInfo(localfileWithFullname);localFileSize = fInfo.Length;}else{throw new Exception("localfile not exists!");}FileStream output = newFileStream(strFolder + "//" + strLocalFileName, FileMode.Append);Socket socketData = CreateDataSocket();SendCommand("REST " + localFileSize.ToString());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>/// 下载一个文件 ,智能判断是重新下载或者断点继续下载/// 1、当本地文件不存在,或者大小等于0, 重新下载/// 2、当本地文件存在, size>0 and size<totalsize,  断点下载/// </summary>/// <param name="strRemoteFileName"></param>/// <param name="strFolder"></param>/// <param name="strLocalFileName"></param>public void GetFileByRestartOrBroken(string strRemoteFileName, string strFolder, string strLocalFileName = ""){strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName);long remoteFileSize = 0;long localFileSize = 0;try{remoteFileSize = this.GetFileSize(strRemoteFileName);}catch (Exception ex){throw new IOException(string.Format("由于 {0} 导致 GetFileByRestartOrBroken 出现异常", ex.Message));}var localfileWithFullname = strFolder + "//" + strLocalFileName;if (File.Exists(localfileWithFullname)){FileInfo fInfo = new FileInfo(localfileWithFullname);localFileSize = fInfo.Length;}else{localFileSize = 0;}if (localFileSize==0){this.Get(strRemoteFileName, strFolder, strLocalFileName);}else{this.GetBrokenFile(strRemoteFileName, strFolder,strLocalFileName);}}/// <summary>/// 下载一个文件/// </summary>/// <param name="strRemoteFileName">要下载的文件名</param>/// <param name="strFolder">本地目录(不得以\结束)</param>/// <param name="strLocalFileName">保存在本地时的文件名</param>public void GetNoBinary(string strRemoteFileName, string strFolder, string strLocalFileName=""){if (!_bConnected){Connect();}strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName);Socket socketData = CreateDataSocket();SendCommand("RETR " + strRemoteFileName);if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250)){throw new IOException(_strReply.Substring(4));}FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);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){Put(strFile);}}/// <summary>/// 上传一个文件/// </summary>/// <param name="strFileName">本地文件名 fullName</param>public void Put(string strFileName){if (!_bConnected){Connect();}Socket socketData = CreateDataSocket();if (Path.GetExtension(strFileName) == "")SendCommand("STOR " + Path.GetFileNameWithoutExtension(strFileName));elseSendCommand("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));}}}/// <summary>/// 上传一个文件,支持断点上传/// </summary>/// <param name="strFileName">localfile with fullName</param>/// <param name="remoteFileName">remoteFilename</param>public void PutBrokenFile(string strFileName,string remoteFileName=""){if (!_bConnected){Connect();}remoteFileName = RegetFileName(strFileName, remoteFileName);long remotefileSize = 0;try{remotefileSize= this.GetFileSize(remoteFileName);}catch (Exception ex){throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常",ex.Message));}try{if (!File.Exists(strFileName)){throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常","待上传的文件不存在"));}var fInfo = new FileInfo(strFileName);var localFilesize = fInfo.Length;if (localFilesize < remotefileSize){throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常", "本地文件小于服务器文件 ,不能再断点上传"));}}catch (Exception ex){throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常", ex.Message));}Socket socketData = CreateDataSocket();if (Path.GetExtension(strFileName) == "")SendCommand("APPE " + Path.GetFileNameWithoutExtension(strFileName));elseSendCommand("APPE " + Path.GetFileName(strFileName));if (!(_iReplyCode == 125 || _iReplyCode == 150)){throw new IOException(_strReply.Substring(4));}FileStream input = new FileStream(strFileName, FileMode.Open);input.Seek(remotefileSize, SeekOrigin.Begin);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));}}}/// <summary>/// 上传一个文件 ,智能判断是重新上传或者断点续传/// 1、当ftp服务器文件不存在,或者大小等于0, 重新下载/// 2、当ftp服务器文件存在, size>0 and size<totalsize, 断点续传/// </summary>/// <param name="localFileName">localfile with fullname</param>/// <param name="remoteFileName">remote file name </param>public void PutFileByRestartOrBroken(string localFileName, string remoteFileName = ""){remoteFileName = RegetFileName(localFileName, remoteFileName);long remoteFileSize = 0;long localFileSize = 0;try{remoteFileSize = this.GetFileSize(remoteFileName);}catch (Exception ex){remoteFileSize = 0;}if (File.Exists(localFileName)){FileInfo fInfo = new FileInfo(localFileName);localFileSize = fInfo.Length;}else{localFileSize = 0;}if (remoteFileSize == 0){this.Put(localFileName);}else{this.PutBrokenFile(localFileName, remoteFileName);}}private static string RegetFileName(string strFileName, string strNullOrNo){string rtnString = "";if (string.IsNullOrEmpty(strNullOrNo)){if (Path.GetExtension(strFileName) == ""){rtnString = Path.GetFileNameWithoutExtension(strFileName);}else{rtnString = Path.GetFileName(strFileName);}}else{rtnString = strNullOrNo;}return rtnString;}/// <summary>/// 上传一个文件/// </summary>/// <param name="strFileName">本地文件名</param>public void PutByGuid(string strFileName, string strGuid){if (!_bConnected){Connect();}string str = strFileName.Substring(0, strFileName.LastIndexOf("\\"));string strTypeName = strFileName.Substring(strFileName.LastIndexOf("."));strGuid = str + "\\" + strGuid;System.IO.File.Copy(strFileName, strGuid);System.IO.File.SetAttributes(strGuid, System.IO.FileAttributes.Normal);Socket socketData = CreateDataSocket();SendCommand("STOR " + Path.GetFileName(strGuid));if (!(_iReplyCode == 125 || _iReplyCode == 150)){throw new IOException(_strReply.Substring(4));}FileStream input = new FileStream(strGuid, FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);int iBytes = 0;while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0){socketData.Send(_buffer, iBytes, 0);}input.Close();File.Delete(strGuid);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>/// 将一行应答字符串记录在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("无法连接ftp服务器");}return s;}/// <summary>/// 关闭socket连接(用于登录以前)/// </summary>private void CloseSocketConnect(){lock (_obj){if (_socketControl != null){_socketControl.Close();_socketControl = null;}_bConnected = false;}}/// <summary>/// 读取Socket返回的所有字符串/// </summary>/// <returns>包含应答码的字符串行</returns>private string ReadLine(){lock (_obj){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];}else{_strMsg = mess[0];}if (!_strMsg.Substring(3, 1).Equals(" ")) //返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串){return ReadLine();}return _strMsg;}/// <summary>/// 发送命令并获取应答码和最后一行应答字符串/// </summary>/// <param name="strCommand">命令</param>public void SendCommand(String strCommand){lock (_obj){//  Byte[] cmdBytes =  Encoding.ASCII.GetBytes((strCommand + "\r\n").ToCharArray());Byte[] cmdBytes = _ASCII.GetBytes((strCommand + "\r\n").ToCharArray());_socketControl.Send(cmdBytes, cmdBytes.Length, 0);Thread.Sleep(500);   ReadReply();}}#endregionpublic void Dispose(){this.DisConnect();}}

  2、 测试代码

 class Program{static void Main(string[] args){// FtpFirstTest();// GetBrokenFileTest();// FileSizeTest();// FtpPutBrokenFile();// SmartGet();SmartPutFile();Console.WriteLine("ftp finished");Console.ReadKey();}private static void FtpFirstTest(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}//  ftp.Put("D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");Console.WriteLine("ftp operation");ftp.GetNoBinary("[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb", "D:\\programShareFile", "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}/// <summary>///    断点下载测试/// </summary>static void GetBrokenFileTest(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}//Console.WriteLine("ftp operation ing"); //ftp.Put("D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");//Console.WriteLine("ftp operation");var localfile = "D:\\programShareFile\\apicloudFtp.zip";if (File.Exists(localfile)){FileInfo fInfo = new FileInfo(localfile);var size = fInfo.Length;Console.WriteLine("file now size=" + size.ToString());ftp.GetBrokenFile("apicloudFtp.zip", "D:\\programShareFile", "apicloudFtp.zip");}else{Console.WriteLine("file not exists");}}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}/// <summary>/// 获取ftp服务器文件大小 测试。  存在的文件  ,不存在的文件/// </summary>static void FileSizeTest(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}Console.WriteLine("ftp operation");var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb";var remoteFile = "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb";var remoteFile2 = "apicloudFtp22.zip";try{var size = ftp.GetFileSize(remoteFile2);Console.WriteLine(string.Format("file size={0}",size));}catch (Exception ex){Console.WriteLine("ftp getfilesize exception ");}}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}/// <summary>/// 测试 ftp 断点上传/// </summary>static void FtpPutBrokenFile(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}Console.WriteLine("ftp operation");var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb";var remoteFile = "apicloudFtp.zip";try{ftp.PutBrokenFile(localfile, "");}catch (Exception ex){Console.WriteLine("ftp.PutBrokenFile exception ");}}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}/// <summary>/// 智能下载测试/// </summary>static void SmartGet(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}Console.WriteLine("ftp operation");// var localfile = "D:\\programShareFile\\apicloudFtp.zip";ftp.GetFileByRestartOrBroken("[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb", "D:\\programShareFile", "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}static void SmartPutFile(){var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];var userName = ConfigurationSettings.AppSettings["userName"];var pwd = ConfigurationSettings.AppSettings["pwd"];try{using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort))){if (!ftp.Connected){ftp.Connect();}Console.WriteLine("ftp operation");var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb";try{ftp.PutFileByRestartOrBroken(localfile);}catch (Exception ex){Console.WriteLine("ftp.PutBrokenFile exception ");}}}catch (Exception ex){Console.WriteLine("ftp exception   msg:" + ex.Message);}}}

  3 config配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup><appSettings><add key="ftpServer" value="127.0.0.1"/><add key="ftpPort" value="21"/><add key="userName" value="hyt"/><add key ="pwd" value="hyt"/></appSettings>
</configuration>

  4  使用到 filezilla server   ftp服务器。测试正常工作

5  为了更加方便的理解ftp原理,附上ftp命令和响应值文档

FTP命令字和响应码解释FTP命令命令     描述
ABOR    中断数据连接程序
ACCT <account>    系统特权帐号
ALLO <bytes>     为服务器上的文件存储器分配字节
APPE <filename>    添加文件到服务器同名文件
CDUP <dir path>    改变服务器上的父目录
CWD <dir path>    改变服务器上的工作目录
DELE <filename>    删除服务器上的指定文件
HELP <command>    返回指定命令信息
LIS2T <name>    如果是文件名列出文件信息,如果是目录则列出文件列表
MODE <mode>    传输模式(S=流模式,B=块模式,C=压缩模式)
MKD <directory>    在服务器上建立指定目录
NLST <directory>    列出指定目录内容
NOOP    无动作,除了来自服务器上的承认
PASS <password>    系统登录密码
PASV    请求服务器等待数据连接
PORT <address>    IP 地址和两字节的端口 ID
PWD    显示当前工作目录
QUIT    从 FTP 服务器上退出登录
REIN    重新初始化登录状态连接
REST <offset>    由特定偏移量重启文件传递
RETR <filename>    从服务器上找回(复制)文件
RMD <directory>    在服务器上删除指定目录
RNFR <old path>    对旧路径重命名
RNTO <new path>    对新路径重命名
SITE <params>    由服务器提供的站点特殊参数
SMNT <pathname>    挂载指定文件结构
STAT <directory>    在当前程序或目录上返回信息
STOR <filename>    储存(复制)文件到服务器上
STOU <filename>    储存文件到服务器名称上
STRU <type>    数据结构(F=文件,R=记录,P=页面)
SYST    返回服务器使用的操作系统
TYPE <data type>    数据类型(A=ASCII,E=EBCDIC,I=binary)
USER <username>>    系统登录的用户名FTP响应码响应代码     解释说明
110    新文件指示器上的重启标记
120    服务器准备就绪的时间(分钟数)
125    打开数据连接,开始传输
150    打开连接
200    成功
202    命令没有执行
211    系统状态回复
212    目录状态回复
213    文件状态回复
214    帮助信息回复
215    系统类型回复
220    服务就绪
221    退出网络
225    打开数据连接
226    结束数据连接
227    进入被动模式(IP 地址、ID 端口)
230    登录因特网
250    文件行为完成
257    路径名建立
331    要求密码
332    要求帐号
350    文件行为暂停
421    服务关闭
425    无法打开数据连接
426    结束连接
450    文件不可用
451    遇到本地错误
452    磁盘空间不足
500    无效命令
501    错误参数
502    命令没有执行
503    错误指令序列
504    无效命令参数
530    未登录网络
532    存储文件需要帐号
550    文件不可用
551    不知道的页类型
552    超过存储分配
553    文件名不允许

转载于:https://www.cnblogs.com/huangkaiyan10/p/swan_ftp.html

ftp 操作,支持断点续传或者继续下载。相关推荐

  1. 那些ftp服务器支持断点续传,ftp服务器 断点续传

    浅谈FTP服务的几个知识点 实现断点续传的条件有三个:1.FTP服务器要能提供断点续传的功能.目前包括IIS和大部分的FTP架设软件都有了这个功能.2.FTP的登录软件要有断点续传的功能.像Flash ...

  2. C# FTP操作(上传、下载等……)

    因为工作中经常涉及到FTP文件的上传和下载,每次有这样的需求时都要重复编写相同的代码,后来干脆整理一个FTPClass,这样不仅方便自己使用,也可以共享给部门其它同事,使用时直接调用就可以了,节省了大 ...

  3. 仿迅雷实现下载工具,支持断点续传和多线程下载以及简单界面展示

    这篇博客介绍一下在公司实习时选做的一个项目,虽然实习期间没有全部完成,但觉得这个项目做好的话挺有意思的,就在之后几天赶着完善了这个项目. 博客最后给出代码地址 这个项目是仿照迅雷,实现一个下载工具. ...

  4. python3多线程断点下载_python支持断点续传的多线程下载示例 -电脑资料

    复制代码代码如下: #! /usr/bin/env python #coding=utf-8 from __future__ import unicode_literals from multipro ...

  5. 基于iOS 10封装的下载器(支持存储读取、断点续传、后台下载、杀死APP重启后的断点续传等功能)

    原文 资源来自:http://www.cocoachina.com/ios/20170316/18901.html 概要 在决定自己封装一个下载器前,我本以为没有那么复杂,可在实际开发过程中困难重重, ...

  6. c#.Net MVC服务端下载文件、限制下载速度、大文件下载、对性能的影响、对大文件的支持、对断点续传和多线程下载的支持

    一.ASP.NET文件下载各种方式比较:对性能的影响.对大文件的支持.对断点续传和多线程下载的支持 asp.net里提供了多种方式,从服务器端向客户端写文件流,实现客户端下载文件.这种技术在做防下载系 ...

  7. 打印 上一主题 下一主题 利用cURL实现单个文件分多段同时下载,支持断点续传(修订版)...

      利用cURL实现单个文件分多段同时下载,支持断点续传(修订版) [复制链接] 摘自 http://bbs.chinaunix.net/thread-917952-1-1.html 在ubuntu下 ...

  8. 自己写的一个简单的迅雷下载支持断点续传

    当我学习了网络线程,就自己仿照迅雷下载写了一个下载器,支持断点续传 我用的是SWT插件做的界面 界面 package com.yc.xunlei; import java.io.File; impor ...

  9. [转]文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)实现汇总1

    转自:http://blog.csdn.net/soarheaven/archive/2008/12/08/3474152.aspx 最近项目需要对FTP服务器进行操作,现把实现总结如下: 打算分2篇 ...

最新文章

  1. 一段神奇的c代码错误分析
  2. Linux C编程--进程间通信(IPC)4--管道详解
  3. Java中对POI的单元格设置背景色
  4. 按键精灵上传账号到服务器_百度网盘超级会员账号登录器
  5. SELinux入门简介
  6. n个数里找出前m个数(或者 从10亿个浮点数中找出最大的1万个)
  7. POJ 2533 Longest Ordered Subsequence 动态规划
  8. (转)Hibernate关联映射——一对多(多对一)
  9. 如何用matlab画圆的图像,matlab在图像上画圆
  10. Stata做KHB中介效应分析
  11. 批处理文件进行音频格式转换
  12. 你知道甲醛的危害有多大吗?
  13. 学会阅读源码后,我觉得自己better了
  14. 微信开源PhxQueue:高可用、高可靠、高性能的分布式队列**
  15. Numerical Summation of a Series
  16. Linux 【进程】
  17. 性能测试指标及测试方法
  18. 不良征信大盘点 这13种情况一定不要犯!
  19. 阿里云服务器配置如何选
  20. java什么是局部与全局变量_Java中的局部VS全局变量

热门文章

  1. OpenCore介绍
  2. 永磁同步电机三相等效电路图_三相永磁同步电机之永磁体的等效
  3. 如何使用git与svn远程仓库协作
  4. 四.javascript对象
  5. c语言生成随机数不用time,C语言生成随机数的函数、延时函数
  6. 华为hg8240光猫破解方法
  7. 设计模式-结构模式-装饰器模式 decorater
  8. Cryptography Assignment(Ⅰ)
  9. 隐马尔科夫模型(HMM):状态序列预测
  10. Mac开发-暗黑主题禁用以及适配