using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
namespace Discuz.Common
{
/// <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");
else
SendCommand("TYPE A");
ReadResponse();
if (response != 200)
Fail();
}
/// <summary>
/// 發送命令
/// </summary>
/// <param name="command"></param>
private void SendCommand(string command)
{
Byte[] cmd = Encoding.ASCII.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.ASCII.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;
}
else
messages += 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 NET1
data_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#else
data_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endif
data_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 blocking
listening_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 NET1
main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#else
main_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endif
main_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);
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);
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);
}
}
}