C#使用Sockets操作FTP【转载】

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;/*
*解析drwxr-xr-x
*第一位表示文件类型。d是目录文件,l是链接文件,-是普通文件,p是管道
*第2-4位表示这个文件的属主拥有的权限,r是读,w是写,x是执行。
*第5-7位表示和这个文件属主所在同一个组的用户所具有的权限。
*第8-10位表示其他用户所具有的权限。
*例如:
* drwxr-xr-x 1 ftp ftp              0 Mar 02  2011 a安全防护
* -r--r--r-- 1 ftp ftp       27772416 Mar 02  2011 0302
*/
namespace JM_IM_COMP.tool
{/// <summary>/// FTP类/// </summary>public class FTP{#region 变量声明/// <summary>/// 服务器连接地址/// </summary>public string server;/// <summary>/// 登陆帐号/// </summary>public string user;/// <summary>/// 登陆口令/// </summary>public string pass;/// <summary>/// 端口号/// </summary>public int port;/// <summary>/// 无响应时间(FTP在指定时间内无响应)/// </summary>public int timeout;/// <summary>/// 服务器错误状态信息/// </summary>public string errormessage;/// <summary>/// 服务器状态返回信息/// </summary>private string messages;/// <summary>/// 服务器的响应信息/// </summary>private string responseStr;/// <summary>/// 链接模式(主动或被动,默认为被动)/// </summary>private bool passive_mode;/// <summary>/// 上传或下载信息字节数/// </summary>private long bytes_total;/// <summary>/// 上传或下载的文件大小/// </summary>private long file_size;/// <summary>/// 主套接字/// </summary>private Socket main_sock;/// <summary>/// 要链接的网络地址终结点/// </summary>private IPEndPoint main_ipEndPoint;/// <summary>/// 侦听套接字/// </summary>private Socket listening_sock;/// <summary>/// 数据套接字/// </summary>private Socket data_sock;/// <summary>/// 要链接的网络数据地址终结点/// </summary>private IPEndPoint data_ipEndPoint;/// <summary>/// 用于上传或下载的文件流对象/// </summary>private FileStream file;/// <summary>/// 与FTP服务器交互的状态值/// </summary>private int response;/// <summary>/// 读取并保存当前命令执行后从FTP服务器端返回的数据信息/// </summary>private string bucket;#endregion#region 构造函数/// <summary>/// 构造函数/// </summary>public FTP(){server = null;user = null;pass = null;port = 21;passive_mode = true;main_sock = null;main_ipEndPoint = null;listening_sock = null;data_sock = null;data_ipEndPoint = null;file = null;bucket = "";bytes_total = 0;timeout = 10000;    //无响应时间为10秒messages = "";errormessage = "";}/// <summary>/// 构造函数/// </summary>/// <param name="server">服务器IP或名称</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>public FTP(string server, string user, string pass){this.server = server;this.user = user;this.pass = pass;port = 21;passive_mode = true;main_sock = null;main_ipEndPoint = null;listening_sock = null;data_sock = null;data_ipEndPoint = null;file = null;bucket = "";bytes_total = 0;timeout = 10000;    //无响应时间为10秒messages = "";errormessage = "";}/// <summary>/// 构造函数/// </summary>/// <param name="server">服务器IP或名称</param>/// <param name="port">端口号</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>public FTP(string server, int port, string user, string pass){this.server = server;this.user = user;this.pass = pass;this.port = port;passive_mode = true;main_sock = null;main_ipEndPoint = null;listening_sock = null;data_sock = null;data_ipEndPoint = null;file = null;bucket = "";bytes_total = 0;timeout = 10000;    //无响应时间为10秒messages = "";errormessage = "";}/// <summary>/// 构造函数/// </summary>/// <param name="server">服务器IP或名称</param>/// <param name="port">端口号</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>/// <param name="mode">链接方式</param>public FTP(string server, int port, string user, string pass, int mode){this.server = server;this.user = user;this.pass = pass;this.port = port;passive_mode = mode <= 1 ? true : false;main_sock = null;main_ipEndPoint = null;listening_sock = null;data_sock = null;data_ipEndPoint = null;file = null;bucket = "";bytes_total = 0;this.timeout = 10000;    //无响应时间为10秒messages = "";errormessage = "";}/// <summary>/// 构造函数/// </summary>/// <param name="server">服务器IP或名称</param>/// <param name="port">端口号</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>/// <param name="mode">链接方式</param>/// <param name="timeout">无响应时间(限时),单位:秒 (小于或等于0为不受时间限制)</param>public FTP(string server, int port, string user, string pass, int mode, int timeout_sec){this.server = server;this.user = user;this.pass = pass;this.port = port;passive_mode = mode <= 1 ? true : false;main_sock = null;main_ipEndPoint = null;listening_sock = null;data_sock = null;data_ipEndPoint = null;file = null;bucket = "";bytes_total = 0;this.timeout = (timeout_sec <= 0) ? int.MaxValue : (timeout_sec * 1000);    //无响应时间messages = "";errormessage = "";}#endregion#region 属性/// <summary>/// 当前是否已连接/// </summary>public bool IsConnected{get{if (main_sock != null)return main_sock.Connected;return false;}}/// <summary>/// 当message缓冲区有数据则返回/// </summary>public bool MessagesAvailable{get{if (messages.Length > 0)return true;return false;}}/// <summary>/// 获取服务器状态返回信息, 并清空messages变量/// </summary>public string Messages{get{string tmp = messages;messages = "";return tmp;}}/// <summary>/// 最新指令发出后服务器的响应/// </summary>public string ResponseString{get{return responseStr;}}/// <summary>///在一次传输中,发送或接收的字节数/// </summary>public long BytesTotal{get{return bytes_total;}}/// <summary>///被下载或上传的文件大小,当文件大小无效时为0/// </summary>public long FileSize{get{return file_size;}}/// <summary>/// 链接模式: /// true 被动模式 [默认]/// false: 主动模式/// </summary>public bool PassiveMode{get{return passive_mode;}set{passive_mode = value;}}#endregion#region 操作/// <summary>/// 操作失败/// </summary>private void Fail(){Disconnect();errormessage += responseStr;//throw new Exception(responseStr);}/// <summary>/// 下载文件类型/// </summary>/// <param name="mode">true:二进制文件 false:字符文件</param>private void SetBinaryMode(bool mode){if (mode)SendCommand("TYPE I");elseSendCommand("TYPE A");ReadResponse();if (response != 200)Fail();}/// <summary>/// 发送命令/// </summary>/// <param name="command"></param>private void SendCommand(string command){Byte[] cmd = Encoding.Default.GetBytes((command + "\r\n").ToCharArray());if (command.Length > 3 && command.Substring(0, 4) == "PASS"){messages = "\rPASS xxx";}else{messages = "\r" + command;}try{main_sock.Send(cmd, cmd.Length, 0);}catch (Exception ex){try{Disconnect();errormessage += ex.Message;return;}catch{main_sock.Close();file.Close();main_sock = null;main_ipEndPoint = null;file = null;}}}private void FillBucket(){Byte[] bytes = new Byte[512];long bytesgot;int msecs_passed = 0;while (main_sock.Available < 1){System.Threading.Thread.Sleep(50);msecs_passed += 50;//当等待时间到,则断开链接if (msecs_passed > timeout){Disconnect();errormessage += "Timed out waiting on server to respond.";return;}}while (main_sock.Available > 0){bytesgot = main_sock.Receive(bytes, 512, 0);bucket += Encoding.Default.GetString(bytes, 0, (int) bytesgot);System.Threading.Thread.Sleep(50);}}private string GetLineFromBucket(){int i;string buf = "";if ((i = bucket.IndexOf('\n')) < 0){while (i < 0){FillBucket();i = bucket.IndexOf('\n');}}buf = bucket.Substring(0, i);bucket = bucket.Substring(i + 1);return buf;}/// <summary>/// 返回服务器端返回信息/// </summary>private void ReadResponse(){string buf;messages = "";while (true){buf = GetLineFromBucket();if (Regex.Match(buf, "^[0-9]+ ").Success){responseStr = buf;response = int.Parse(buf.Substring(0, 3));break;}elsemessages += Regex.Replace(buf, "^[0-9]+-", "") + "\n";}}/// <summary>/// 打开数据套接字/// </summary>private void OpenDataSocket(){if (passive_mode){string[] pasv;string server;int port;Connect();SendCommand("PASV");ReadResponse();if (response != 227)Fail();try{int i1, i2;i1 = responseStr.IndexOf('(') + 1;i2 = responseStr.IndexOf(')') - i1;pasv = responseStr.Substring(i1, i2).Split(',');}catch (Exception){Disconnect();errormessage += "Malformed PASV response: " + responseStr;return;}if (pasv.Length < 6){Disconnect();errormessage += "Malformed PASV response: " + responseStr;return;}server = String.Format("{0}.{1}.{2}.{3}", pasv[0], pasv[1], pasv[2], pasv[3]);port = (int.Parse(pasv[4]) << 8) + int.Parse(pasv[5]);try{CloseDataSocket();data_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);#if NET1data_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#elsedata_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endifdata_sock.Connect(data_ipEndPoint);}catch (Exception ex){errormessage += "Failed to connect for data transfer: " + ex.Message;return;}}else{Connect();try{CloseDataSocket();listening_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 对于端口,则发送IP地址.下面则提取相应信息string sLocAddr = main_sock.LocalEndPoint.ToString();int ix = sLocAddr.IndexOf(':');if (ix < 0){errormessage += "Failed to parse the local address: " + sLocAddr;return;}string sIPAddr = sLocAddr.Substring(0, ix);// 系统自动绑定一个端口号(设置 port = 0)System.Net.IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(sIPAddr), 0);listening_sock.Bind(localEP);sLocAddr = listening_sock.LocalEndPoint.ToString();ix = sLocAddr.IndexOf(':');if (ix < 0){errormessage += "Failed to parse the local address: " + sLocAddr;}int nPort = int.Parse(sLocAddr.Substring(ix + 1));// 开始侦听链接请求listening_sock.Listen(1);string sPortCmd = string.Format("PORT {0},{1},{2}",sIPAddr.Replace('.', ','),nPort / 256, nPort % 256);SendCommand(sPortCmd);ReadResponse();if (response != 200)Fail();}catch (Exception ex){errormessage += "Failed to connect for data transfer: " + ex.Message;return;}}}private void ConnectDataSocket(){if (data_sock != null)        // 已链接return;try{data_sock = listening_sock.Accept();    // Accept is blockinglistening_sock.Close();listening_sock = null;if (data_sock == null){throw new Exception("Winsock error: " +Convert.ToString(System.Runtime.InteropServices.Marshal.GetLastWin32Error()));}}catch (Exception ex){errormessage += "Failed to connect for data transfer: " + ex.Message;}}private void CloseDataSocket(){if (data_sock != null){if (data_sock.Connected){data_sock.Close();}data_sock = null;}data_ipEndPoint = null;}/// <summary>/// 关闭所有链接/// </summary>public void Disconnect(){CloseDataSocket();if (main_sock != null){if (main_sock.Connected){SendCommand("QUIT");main_sock.Close();}main_sock = null;}if (file != null)file.Close();main_ipEndPoint = null;file = null;}/// <summary>/// 链接到FTP服务器/// </summary>/// <param name="server">要链接的IP地址或主机名</param>/// <param name="port">端口号</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>public void Connect(string server, int port, string user, string pass){this.server = server;this.user = user;this.pass = pass;this.port = port;Connect();}/// <summary>/// 链接到FTP服务器/// </summary>/// <param name="server">要链接的IP地址或主机名</param>/// <param name="user">登陆帐号</param>/// <param name="pass">登陆口令</param>public void Connect(string server, string user, string pass){this.server = server;this.user = user;this.pass = pass;Connect();}/// <summary>/// 链接到FTP服务器/// </summary>public bool Connect(){if (server == null){errormessage += "No server has been set.\r\n";}if (user == null){errormessage += "No server has been set.\r\n";}if (main_sock != null)if (main_sock.Connected)return true;try{main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if NET1main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#elsemain_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endifmain_sock.Connect(main_ipEndPoint);}catch (Exception ex){errormessage += ex.Message;return false;}ReadResponse();if (response != 220)Fail();SendCommand("USER " + user);ReadResponse();switch (response){case 331:if (pass == null){Disconnect();errormessage += "No password has been set.";return false;}SendCommand("PASS " + pass);ReadResponse();if (response != 230){Fail();return false;}break;case 230:break;}return true;}/// <summary>/// 获取FTP当前(工作)目录下的文件列表/// </summary>/// <returns>返回文件列表数组</returns>public ArrayList List(){Byte[] bytes = new Byte[512];string file_list = "";long bytesgot = 0;int msecs_passed = 0;ArrayList list = new ArrayList();Connect();OpenDataSocket();SendCommand("LIST");ReadResponse();switch (response){case 125:case 150:break;default:CloseDataSocket();throw new Exception(responseStr);}ConnectDataSocket();while (data_sock.Available < 1){System.Threading.Thread.Sleep(50);msecs_passed += 50;if (msecs_passed > (timeout / 10)){break;}}while (data_sock.Available > 0){bytesgot = data_sock.Receive(bytes, bytes.Length, 0);//file_list += Encoding.ASCII.GetString(bytes, 0, (int) bytesgot);file_list += Encoding.Default.GetString(bytes, 0, (int)bytesgot);System.Threading.Thread.Sleep(50);}CloseDataSocket();ReadResponse();if (response != 226)throw new Exception(responseStr);foreach (string f in file_list.Split('\n')){if (f.Length > 0 && !Regex.Match(f, "^total").Success)list.Add(f.Substring(0, f.Length - 1));}return list;}/// <summary>/// 获取到文件名列表/// </summary>/// <returns>返回文件名列表</returns>public ArrayList ListFiles(){ArrayList list = new ArrayList();foreach (string f in List()){if ((f.Length > 0)){if ((f[0] != 'd') && (f.ToUpper().IndexOf("<DIR>") < 0))list.Add(f);}}return list;}/// <summary>/// 获取路径列表/// </summary>/// <returns>返回路径列表</returns>public ArrayList ListDirectories(){ArrayList list = new ArrayList();foreach (string f in List()){if (f.Length > 0){if ((f[0] == 'd') || (f.ToUpper().IndexOf("<DIR>") >= 0))list.Add(f);}}return list;}/// <summary>/// 获取原始数据信息./// </summary>/// <param name="fileName">远程文件名</param>/// <returns>返回原始数据信息.</returns>public string GetFileDateRaw(string fileName){Connect();SendCommand("MDTM " + fileName);ReadResponse();if (response != 213){errormessage += responseStr;return "";}return (this.responseStr.Substring(4));}/// <summary>/// 得到文件日期./// </summary>/// <param name="fileName">远程文件名</param>/// <returns>返回远程文件日期</returns>public DateTime GetFileDate(string fileName){return ConvertFTPDateToDateTime(GetFileDateRaw(fileName));}private DateTime ConvertFTPDateToDateTime(string input){if (input.Length < 14)throw new ArgumentException("Input Value for ConvertFTPDateToDateTime method was too short.");//YYYYMMDDhhmmss": int year = Convert.ToInt16(input.Substring(0, 4));int month = Convert.ToInt16(input.Substring(4, 2));int day = Convert.ToInt16(input.Substring(6, 2));int hour = Convert.ToInt16(input.Substring(8, 2));int min = Convert.ToInt16(input.Substring(10, 2));int sec = Convert.ToInt16(input.Substring(12, 2));return new DateTime(year, month, day, hour, min, sec);}/// <summary>/// 获取FTP上的当前(工作)路径/// </summary>/// <returns>返回FTP上的当前(工作)路径</returns>public string GetWorkingDirectory(){//PWD - 显示工作路径Connect();SendCommand("PWD");ReadResponse();if (response != 257){errormessage += responseStr;}string pwd;try{pwd = responseStr.Substring(responseStr.IndexOf("\"", 0) + 1);//5);pwd = pwd.Substring(0, pwd.LastIndexOf("\""));pwd = pwd.Replace("\"\"", "\""); // 替换带引号的路径信息符号}catch (Exception ex){errormessage += ex.Message;return null;}return pwd;}/// <summary>/// 跳转服务器上的当前(工作)路径/// </summary>/// <param name="path">要跳转的路径</param>public bool ChangeDir(string path){Connect();SendCommand("CWD " + path);ReadResponse();if (response != 250){errormessage += responseStr;return false;}return true;}/// <summary>/// 创建指定的目录/// </summary>/// <param name="dir">要创建的目录</param>public void MakeDir(string dir){Connect();SendCommand("MKD " + dir);ReadResponse();switch (response){case 257:case 250:break;default:{errormessage += responseStr;break;}}}/// <summary>/// 移除FTP上的指定目录/// </summary>/// <param name="dir">要移除的目录</param>public void RemoveDir(string dir){Connect();SendCommand("RMD " + dir);ReadResponse();if (response != 250){errormessage += responseStr;return;;}}/// <summary>/// 移除FTP上的指定文件/// </summary>/// <param name="filename">要移除的文件名称</param>public void RemoveFile(string filename){Connect();SendCommand("DELE " + filename);ReadResponse();if (response != 250){errormessage += responseStr;}}/// <summary>/// 重命名FTP上的文件/// </summary>/// <param name="oldfilename">原文件名</param>/// <param name="newfilename">新文件名</param>public void RenameFile(string oldfilename, string newfilename){Connect();SendCommand("RNFR " + oldfilename);ReadResponse();if (response != 350){errormessage += responseStr;}else{SendCommand("RNTO " + newfilename);ReadResponse();if (response != 250){errormessage += responseStr;}}}/// <summary>/// 获得指定文件的大小(如果FTP支持)/// </summary>/// <param name="filename">指定的文件</param>/// <returns>返回指定文件的大小</returns>public long GetFileSize(string filename){Connect();SendCommand("SIZE " + filename);ReadResponse();if (response != 213){errormessage += responseStr;}return Int64.Parse(responseStr.Substring(4));}/// <summary>/// 上传指定的文件/// </summary>/// <param name="filename">要上传的文件</param>public bool OpenUpload(string filename){return OpenUpload(filename, filename, false);}/// <summary>/// 上传指定的文件/// </summary>/// <param name="filename">本地文件名</param>/// <param name="remotefilename">远程要覆盖的文件名</param>public bool OpenUpload(string filename, string remotefilename){return OpenUpload(filename, remotefilename, false);}/// <summary>/// 上传指定的文件/// </summary>/// <param name="filename">本地文件名</param>/// <param name="resume">如果存在,则尝试恢复</param>public bool OpenUpload(string filename, bool resume){return OpenUpload(filename, filename, resume);}/// <summary>/// 上传指定的文件/// </summary>/// <param name="filename">本地文件名</param>/// <param name="remote_filename">远程要覆盖的文件名</param>/// <param name="resume">如果存在,则尝试恢复</param>public bool OpenUpload(string filename, string remote_filename, bool resume){Connect();SetBinaryMode(true);OpenDataSocket();bytes_total = 0;try{file = new FileStream(filename, FileMode.Open);}catch (Exception ex){file = null;errormessage += ex.Message;return false;}file_size = file.Length;if (resume){long size = GetFileSize(remote_filename);SendCommand("REST " + size);ReadResponse();if (response == 350)file.Seek(size, SeekOrigin.Begin);}SendCommand("STOR " + remote_filename);ReadResponse();switch (response){case 125:case 150:break;default:file.Close();file = null;errormessage += responseStr;return false;}ConnectDataSocket();return true;}/// <summary>/// 下载指定文件/// </summary>/// <param name="filename">远程文件名称</param>public void OpenDownload(string filename){OpenDownload(filename, filename, false);}/// <summary>/// 下载并恢复指定文件/// </summary>/// <param name="filename">远程文件名称</param>/// <param name="resume">如文件存在,则尝试恢复</param>public void OpenDownload(string filename, bool resume){OpenDownload(filename, filename, resume);}/// <summary>/// 下载指定文件/// </summary>/// <param name="filename">远程文件名称</param>/// <param name="localfilename">本地文件名</param>public void OpenDownload(string remote_filename, string localfilename){OpenDownload(remote_filename, localfilename, false);}/// <summary>/// 打开并下载文件/// </summary>/// <param name="remote_filename">远程文件名称</param>/// <param name="local_filename">本地文件名</param>/// <param name="resume">如果文件存在则恢复</param>public void OpenDownload(string remote_filename, string local_filename, bool resume){Connect();SetBinaryMode(true);bytes_total = 0;try{file_size = GetFileSize(remote_filename);}catch{file_size = 0;}if (resume && File.Exists(local_filename)){try{file = new FileStream(local_filename, FileMode.Open);}catch (Exception ex){file = null;throw new Exception(ex.Message);}SendCommand("REST " + file.Length);ReadResponse();if (response != 350)throw new Exception(responseStr);file.Seek(file.Length, SeekOrigin.Begin);bytes_total = file.Length;}else{try{file = new FileStream(local_filename, FileMode.Create);}catch (Exception ex){file = null;throw new Exception(ex.Message);}}OpenDataSocket();SendCommand("RETR " + remote_filename);ReadResponse();switch (response){case 125:case 150:break;default:file.Close();file = null;errormessage += responseStr;return;}ConnectDataSocket();return;}/// <summary>/// 上传文件(循环调用直到上传完毕)/// </summary>/// <returns>发送的字节数</returns>public long DoUpload(){Byte[] bytes = new Byte[512];long bytes_got;try{bytes_got = file.Read(bytes, 0, bytes.Length);bytes_total += bytes_got;data_sock.Send(bytes, (int) bytes_got, 0);if (bytes_got <= 0){//上传完毕或有错误发生file.Close();file = null;CloseDataSocket();ReadResponse();switch (response){case 226:case 250:break;default: //当上传中断时{errormessage += responseStr;return -1;}}SetBinaryMode(false);}}catch (Exception ex){file.Close();file = null;CloseDataSocket();ReadResponse();SetBinaryMode(false);//throw ex;//当上传中断时errormessage += ex.Message;return -1;}return bytes_got;}/// <summary>/// 下载文件(循环调用直到下载完毕)/// </summary>/// <returns>接收到的字节点</returns>public long DoDownload(){Byte[] bytes = new Byte[512];long bytes_got;try{bytes_got = data_sock.Receive(bytes, bytes.Length, 0);if (bytes_got <= 0){//下载完毕或有错误发生CloseDataSocket();file.Close();file = null;ReadResponse();switch (response){case 226:case 250:break;default:{errormessage += responseStr;return -1;}}//SetBinaryMode(false);SetBinaryMode(true);//业务需要,使用二进制模式下载return bytes_got;}file.Write(bytes, 0, (int) bytes_got);bytes_total += bytes_got;}catch (Exception ex){CloseDataSocket();file.Close();file = null;ReadResponse();SetBinaryMode(false);//throw ex;//当下载中断时errormessage += ex.Message;return -1;}return bytes_got;}#endregion}
}

 使用例子:

using System;
using System.Collections;
using System.IO;
using Discuz.Common;namespace Test
{class TestFtp{public void Test(){FTP ftp = new FTP("127.0.0.1", "abc", "123456");//建立文件夹ftp.MakeDir("com");ftp.ChangeDir("com");ftp.MakeDir("mzwu");ftp.ChangeDir("mzwu");//文件夹列表ArrayList list = ftp.ListDirectories();for (int i = 0; i < list.Count; i++){Console.WriteLine(list[i].ToString() + "<br/>");}//删除文件夹(不能直接删除非空文件夹)ftp.RemoveDir("com\\mzwu");//上传文件ftp.Connect();ftp.OpenUpload(@"F:\mzwucom.jpg", Path.GetFileName(@"F:\mzwucom.jpg"));while (ftp.DoUpload() > 0){int perc = (int) (((ftp.BytesTotal) * 100) / ftp.FileSize);Console.WriteLine(perc.ToString() + "%<br/>");}ftp.Disconnect();//下载文件ftp.Connect();ftp.OpenDownload("mzwucom.jpg", @"E:\mzwucom.jpg");while (ftp.DoDownload() > 0){int perc = (int) (((ftp.BytesTotal) * 100) / ftp.FileSize);Console.WriteLine(perc.ToString() + "%<br/>");}ftp.Disconnect();//文件列表list = ftp.ListFiles();for (int i = 0; i < list.Count; i++){Console.WriteLine(list[i].ToString() + "<br/>");}//文件重命名ftp.RenameFile("mzwucom.jpg", "test.jpg");//删除文件ftp.RemoveFile("test.jpg");//显示错误信息Console.WriteLine(ftp.errormessage);}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scala 字符串占位符_如何在Scala中将带有换行符的字符串转换为字符串列表?

scala 字符串占位符A string is a sequence of characters and it can contain multiple lines, for this, the string uses the newline character \n. And, we can separate each newline into a string and store them as a list of strings. 字符串是字符序列&#xff0c;…

一款开源免费的SSH/SFTP客户端Electerm,同时支持Linux、MacOS、Windows

简介&#xff1a; Electerm是一个跨平台的Terminal/SSH/SFTP客户端工具&#xff0c;同时支持Linux、MacOS、Windows&#xff0c;基于electron/ssh2/node-pty/xterm/antd/useProxy等开源组件。 下载地址&#xff1a; 官网下载&#xff1a;https://electerm.html5beta.com/ Git…

用了自定义Banner后,SpringBoot瞬间变的高大上了...

Spring Boot 在启动的时候&#xff0c;我们或许想要把自己公司的 logo&#xff0c;或者是项目的 logo 放上去&#xff0c;我们可以试试本文的这些方法&#xff0c;可以让你快速制作一些 Spring Boot 项目启动时的彩蛋&#xff0c;以提高项目的辨识度&#xff0c;或者是纯碎为了…

菜鸟学前端--javascript基础

在学习过css相关的知识&#xff0c;有了前端工程师的一些基础知识。但要较好的掌握前端&#xff0c;必须要学习好javascript的知识。下面将从基本语法、变量、关键字、保留字、语句、函数、BOM等角度阐释。一、基本语法javacript作为一种面向对象的、脚本级的轻量语言&#xff…

Java LinkedList void add(int index,Object o)方法,带示例

LinkedList void add(int index&#xff0c;Object o)方法 (LinkedList void add(int index, Object o) method) This method is available in package java.util.Collection and here, Collection is an interface. 该方法在java.util.Collection包中可用&#xff0c;在这里&a…

如何生成高性能的短链接?

前言今天&#xff0c;我们来谈谈如何设计一个高性能短链系统&#xff0c;短链系统设计看起来很简单&#xff0c;但每个点都能展开很多知识点&#xff0c;也是在面试中非常适合考察侯选人的一道设计题&#xff0c;本文将会结合我们生产上稳定运行两年之久的高性能短链系统给大家…

iOS 技术官方 QA

2019独角兽企业重金招聘Python工程师标准>>> Q: 在静态库中使用catagory分类运行时提示"selector not recognized" A: 需要配置下project/target属性 Q: 在iOS7以后怎么截图 A: iOS7 提供了相关API实现截图功能&#xff0c;如:-drawViewHierarchyInRect:a…

Python日历模块| weekheader()方法与示例

Python calendar.weekheader()方法 (Python calendar.weekheader() Method) weekheader() method is an inbuilt method of the calendar module in Python. It works on simple text calendars and returns a header containing the abbreviated names of the weekday. weekhe…

IPsec IKEv2(HCIP)

目录 一、IKE介绍 1、IKE介绍 2、IKE的主要作用 3、IKE与IPsec关系 二、IKE基础内容 1、IEK的身份认证方法 数据源认证 预共享密钥PSK 数字证书 数字信封 EAP(IKEv2支持) 数字证书CA如何实现身份认证? 2、IKEv1介绍 IKEv1介绍 IKEv1第一阶段介绍 IKEv1第二阶段…

9个小技巧让你的 if else看起来更优雅

if else 是我们写代码时&#xff0c;使用频率最高的关键词之一&#xff0c;然而有时过多的 if else 会让我们感到脑壳疼&#xff0c;例如下面这个伪代码&#xff1a; 是不是很奔溃&#xff1f;虽然他是伪代码&#xff0c;并且看起来也很夸张&#xff0c;但在现实中&#xff0c;…

poj 3254 状压dp

E -Corn FieldsTime Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u SubmitStatus Practice POJ 3254Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels…

第一弹!安利10个让你爽到爆的IDEA必备插件!

大家好&#xff0c;此篇文章中我会介绍10个非常不错的IDEA插件以及它们常见功能的使用方法。这一期内容搞 Gif 动态图花了很久&#xff0c;很多Gif图片上传到微信还提示过大&#xff0c;所以很多地方重新又录制了一遍Gif图。概览&#xff1a;IDE Features Trainer—IDEA交互式教…

C程序对整数中设置为1的位数进行计数

Problem statement: Write a C program to count number of bits set to 1 in an Integer. 问题陈述&#xff1a;编写一个C程序来计算Integer中设置为1的位数 。 Solution: We can use bitwise operator here to solve the problem. 解决方案&#xff1a;我们可以在这里使用按…

String性能提升10倍的几个方法!(源码+原理分析)

这是我的第 54 篇原创文章。String 类型是我们使用最频繁的数据类型&#xff0c;没有之一。那么提高 String 的运行效率&#xff0c;无疑是提升程序性能的最佳手段。我们本文将从 String 的源码入手&#xff0c;一步步带你实现字符串优化的小目标。不但教你如何有效的使用字符串…

日期getTime()方法以及JavaScript中的示例

JavaScript Date getTime()方法 (JavaScript Date getTime() method) getTime() method is a Dates class method and it is used to get the time in milliseconds from 1st January 1970. getTime()方法是Date的类方法&#xff0c;用于获取从1970年1月1 日开始的时间(以毫秒为…

制作openstack-centos镜像

一、准备工作我在计算节点上面制作镜像&#xff0c;计算节点为centos6.3 64位系统1.安装底层支持包yum groupinstall Virtualization "Virtualization Client"yum install libvirt2.下载或从本地上传进去一个完整的系统镜像mkdir /openstack-p_w_picpathcd /openstac…

一文彻底搞懂Java中的值传递和引用传递!

关于Java中方法间的参数传递到底是怎样的、为什么很多人说Java只有值传递等问题&#xff0c;一直困惑着很多人&#xff0c;甚至我在面试的时候问过很多有丰富经验的开发者&#xff0c;他们也很难解释的很清楚。我很久也写过一篇文章&#xff0c;我当时认为我把这件事说清楚了&a…

g++默认参数_C ++默认参数| 查找输出程序| 套装1

g默认参数Program 1: 程序1&#xff1a; #include <iostream>using namespace std;int sum(int X, int Y 20, int Z 30){return (X Y Z);}int main(){int A 0, B 0;A sum(5, 10);B sum(10);cout << A << " " << B;return 0;}Output…

c语言指针灵活性管窥

最近看到mit的[urlhttp://pdos.csail.mit.edu/6.828/2010/]操作系统课程网站[/url],其[urlhttp://pdos.csail.mit.edu/6.828/2010/labs/lab1/]实验一[/url] 中练习四&#xff08;exercise 4&#xff09;中有一个关于指针使用的代码&#xff1a;#include <stdio.h>#includ…

近100个Spring/SpringBoot常用注解汇总!

作者 | Guide来源 | JavaGuide&#xff08;微信公众号&#xff09;毫不夸张地说&#xff0c;这篇文章介绍的 Spring/SpringBoot 常用注解基本已经涵盖你工作中遇到的大部分常用的场景。对于每一个注解我都说了具体用法&#xff0c;掌握搞懂&#xff0c;使用 SpringBoot 来开发项…