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
{
/// <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;
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;
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;
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;
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;
}
/// <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);
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);
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();
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."
);
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()
{
Connect();
SendCommand(
"PWD"
);
ReadResponse();
if
(response != 257)
{
errormessage += responseStr;
}
string
pwd;
try
{
pwd = responseStr.Substring(responseStr.IndexOf(
"\""
, 0) + 1);
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
);
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
);
errormessage += ex.Message;
return
-1;
}
return
bytes_got;
}
#endregion
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术