|
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
namespace Discuz.Common
{
///
/// FTP类
///
public class FTP
{
#region 变量声明
///
/// 服务器连接地址
///
public string server;
///
/// 登陆帐号
///
public string user;
///
/// 登陆口令
///
public string pass;
///
/// 端口号
///
public int port;
///
/// 无响应时间(FTP在指定时间内无响应)
///
public int timeout;
///
/// 服务器错误状态信息
///
public string errormessage;
///
/// 服务器状态返回信息
///
private string messages;
///
/// 服务器的响应信息
///
private string responseStr;
///
/// 链接模式(主动或被动,默认为被动)
///
private bool passive_mode;
///
/// 上传或下载信息字节数
///
private long bytes_total;
///
/// 上传或下载的文件大小
///
private long file_size;
///
/// 主套接字
///
private Socket main_sock;
///
/// 要链接的网络地址终结点
///
private IPEndPoint main_ipEndPoint;
///
/// 侦听套接字
///
private Socket listening_sock;
///
/// 数据套接字
///
private Socket data_sock;
///
/// 要链接的网络数据地址终结点
///
private IPEndPoint data_ipEndPoint;
///
/// 用于上传或下载的文件流对象
///
private FileStream file;
///
/// 与FTP服务器交互的状态值
///
private int response;
///
/// 读取并保存当前命令执行后从FTP服务器端返回的数据信息
///
private string bucket;
#endregion
#region 构造函数
///
/// 构造函数
///
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 = "";
}
///
/// 构造函数
///
/// 服务器IP或名称
/// 登陆帐号
/// 登陆口令
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 = "";
}
///
/// 构造函数
///
/// 服务器IP或名称
/// 端口号
/// 登陆帐号
/// 登陆口令
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 = "";
}
///
/// 构造函数
///
/// 服务器IP或名称
/// 端口号
/// 登陆帐号
/// 登陆口令
/// 链接方式
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 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;
}
///
/// 返回服务器端返回信息
///
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";
}
}
///
/// 打开数据套接字
///
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]) (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;
}
///
/// 获取到文件名列表
///
/// 返回文件名列表
public ArrayList ListFiles()
{
ArrayList list = new ArrayList();
foreach (string f in List())
{
if ((f.Length > 0))
{
if ((f[0] != 'd') && (f.ToUpper().IndexOf("") < 0))
list.Add(f);
}
}
return list;
}
///
/// 获取路径列表
///
/// 返回路径列表
public ArrayList ListDirectories()
{
ArrayList list = new ArrayList();
foreach (string f in List())
{
if (f.Length > 0)
{
if ((f[0] == 'd') || (f.ToUpper().IndexOf("") >= 0))
list.Add(f);
}
}
return list;
}
///
/// 获取原始数据信息.
///
/// 远程文件名
/// 返回原始数据信息.
public string GetFileDateRaw(string fileName)
{
Connect();
SendCommand("MDTM " + fileName);
ReadResponse();
if (response != 213)
{
errormessage += responseStr;
return "";
}
return (this.responseStr.Substring(4));
}
///
/// 得到文件日期.
///
/// 远程文件名
/// 返回远程文件日期
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);
}
///
/// 获取FTP上的当前(工作)路径
///
/// 返回FTP上的当前(工作)路径
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;
}
///
/// 跳转服务器上的当前(工作)路径
///
/// 要跳转的路径
public bool ChangeDir(string path)
{
Connect();
SendCommand("CWD " + path);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
return false;
}
return true;
}
///
/// 创建指定的目录
///
/// 要创建的目录
public void MakeDir(string dir)
{
Connect();
SendCommand("MKD " + dir);
ReadResponse();
switch (response)
{
case 257:
case 250:
break;
default:
{
errormessage += responseStr;
break;
}
}
}
///
/// 移除FTP上的指定目录
///
/// 要移除的目录
public void RemoveDir(string dir)
{
Connect();
SendCommand("RMD " + dir);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
return; ;
}
}
///
/// 移除FTP上的指定文件
///
/// 要移除的文件名称
public void RemoveFile(string filename)
{
Connect();
SendCommand("DELE " + filename);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
}
}
///
/// 重命名FTP上的文件
///
/// 原文件名
/// 新文件名
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;
}
}
}
///
/// 获得指定文件的大小(如果FTP支持)
///
/// 指定的文件
/// 返回指定文件的大小
public long GetFileSize(string filename)
{
Connect();
SendCommand("SIZE " + filename);
ReadResponse();
if (response != 213)
{
errormessage += responseStr;
}
return Int64.Parse(responseStr.Substring(4));
}
///
/// 上传指定的文件
///
/// 要上传的文件
public bool OpenUpload(string filename)
{
return OpenUpload(filename, filename, false);
}
///
/// 上传指定的文件
///
/// 本地文件名
/// 远程要覆盖的文件名
public bool OpenUpload(string filename, string remotefilename)
{
return OpenUpload(filename, remotefilename, false);
}
///
/// 上传指定的文件
///
/// 本地文件名
/// 如果存在,则尝试恢复
public bool OpenUpload(string filename, bool resume)
{
return OpenUpload(filename, filename, resume);
}
///
/// 上传指定的文件
///
/// 本地文件名
/// 远程要覆盖的文件名
/// 如果存在,则尝试恢复
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;
}
///
/// 下载指定文件
///
/// 远程文件名称
public void OpenDownload(string filename)
{
OpenDownload(filename, filename, false);
}
///
/// 下载并恢复指定文件
///
/// 远程文件名称
/// 如文件存在,则尝试恢复
public void OpenDownload(string filename, bool resume)
{
OpenDownload(filename, filename, resume);
}
///
/// 下载指定文件
///
/// 远程文件名称
/// 本地文件名
public void OpenDownload(string remote_filename, string localfilename)
{
OpenDownload(remote_filename, localfilename, false);
}
///
/// 打开并下载文件
///
/// 远程文件名称
/// 本地文件名
/// 如果文件存在则恢复
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;
}
///
/// 上传文件(循环调用直到上传完毕)
///
/// 发送的字节数
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)
{
int perc = (int)(((ftp.BytesTotal) * 100) / ftp.FileSize);
Response.Write(perc.ToString() + "%");
Response.Flush();
}
ftp.Disconnect();
}
}
//下载文件
if (ftp.Connect())
{
ftp.OpenDownload("mzwucom.jpg", @"E:\mzwucom.jpg");
while (ftp.DoDownload() > 0)
{
int perc = (int)(((ftp.BytesTotal) * 100) / ftp.FileSize);
Response.Write(perc.ToString() + "%");
Response.Flush();
}
ftp.Disconnect();
}
//文件列表
ArrayList list = ftp.ListFiles();
for (int i = 0; i < list.Count; i++)
{
Response.Write(list.ToString() + "");
}
//文件重命名
ftp.RenameFile("mzwucom.jpg", "test.jpg");
//删除文件
ftp.RemoveFile("test.jpg");
//显示错误信息
Response.Write(ftp.errormessage);
|
|