public class FTPClient
{
#region
构造函数
///
<summary>
///
缺省构造函数
/// </summary>
public
FTPClient()
{
strRemoteHost =
"";
strRemotePath =
"/";
strRemoteUser =
"";
strRemotePass =
"";
strRemotePort =
21;
bConnected =
false;
}
/// <summary>
/// 构造函数
///
</summary>
///
<param name="remoteHost"></param>
///
<param name="remotePath"></param>
///
<param name="remoteUser"></param>
///
<param name="remotePass"></param>
///
<param name="remotePort"></param>
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 登陆
/// <summary>
///
FTP服务器IP地址
///
</summary>
private
string
strRemoteHost;
public string
RemoteHost
{
get
{
return
strRemoteHost;
}
set
{
strRemoteHost =
value;
}
}
///
<summary>
///
FTP服务器端口
/// </summary>
private
int
strRemotePort;
public int
RemotePort
{
get
{
return
strRemotePort;
}
set
{
strRemotePort =
value;
}
}
///
<summary>
///
当前服务器目录
/// </summary>
private
string
strRemotePath;
public string
RemotePath
{
get
{
return
strRemotePath;
}
set
{
strRemotePath =
value;
}
}
///
<summary>
///
登录用户账号
/// </summary>
private
string
strRemoteUser;
public string
RemoteUser
{
set
{
strRemoteUser =
value;
}
}
///
<summary>
///
用户登录密码
/// </summary>
private
string
strRemotePass;
public string
RemotePass
{
set
{
strRemotePass =
value;
}
} ///
<summary>
/// 是否登录
///
</summary>
private
Boolean
bConnected;
public bool
Connected
{
get
{
return
bConnected;
}
}
#endregion
#region 链接
/// <summary>
///
建立连接
///
</summary>
public
void
Connect()
{
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("Couldn‘t connect to remote
server");
} // 获取应答码
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>
///
<returns></returns>
public
string[] Dir(string
strMask)
{
// 建立链接
if
(!bConnected)
{
Connect();
} //建立进行数据连接的socket
Socket socketData =
CreateDataSocket();
//传送命令
SendCommand("NLST " + strMask); //分析应答代码
if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode ==
226))
{
throw new
IOException(strReply.Substring(4));
} //获得结果
strMsg =
"";
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;
}
///
<summary>
///
获取文件大小
/// </summary>
///
<param name="strFileName">文件名</param>
///
<returns>文件大小</returns>
private
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>
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">保存在本地时的文件名
public
void Get(string strRemoteFileName, string strFolder, string
strLocalFileName)
{
if
(!bConnected)
{
Connect();
}
SetTransferType(TransferType.Binary);
if
(strLocalFileName.Equals(""))
{
strLocalFileName =
strRemoteFileName;
}
if
(!File.Exists(strLocalFileName))
{
Stream st =
File.Create(strLocalFileName);
st.Close();
}
FileStream output =
new
FileStream(strFolder + "\\" + strLocalFileName,
FileMode.Create);
Socket socketData =
CreateDataSocket();
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>
///
上传一批文件
/// </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)
{
//strFile是完整的文件名(包含路径)
Put(strFile);
}
}
///
<summary>
///
上传一个文件
/// </summary>
///
<param name="strFileName">本地文件名</param>
public
void Put(string
strFileName)
{
if
(!bConnected)
{
Connect();
}
Socket socketData =
CreateDataSocket();
SendCommand("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));
}
}
}
#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>
///
服务器返回的应答信息(包含应答码)
///
</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;
Byte[] buffer = new
Byte[BLOCK_SIZE];
/// <summary>
/// 编码方式
///
</summary>
Encoding
ASCII =
Encoding.ASCII;
#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("Can‘t connect to remote
server");
}
return s;
}
///
<summary>
///
关闭socket连接(用于登录以前)
///
</summary>
private
void
CloseSocketConnect()
{
if (socketControl !=
null)
{
socketControl.Close();
socketControl =
null;
}
bConnected =
false;
}
///
<summary>
///
读取Socket返回的所有字符串
///
</summary>
///
<returns>包含应答码的字符串行</returns>
private
string
ReadLine()
{
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(" "))//返回字符串正
{
return
ReadLine();
}
return
strMsg;
}
///
<summary>
///
发送命令并获取应答码和最后一行应答字符串
///
</summary>
///
<param name="strCommand">命令</param>
private
void SendCommand(String
strCommand)
{
Byte[] cmdBytes = Encoding.ASCII.GetBytes((strCommand +
"\r\n").ToCharArray());
socketControl.Send(cmdBytes, cmdBytes.Length,
0);
ReadReply();
}
#endregion
}
C#上传下载文件ftp操作类FTPClient代码,布布扣,bubuko.com
原文:http://www.cnblogs.com/shizhongyi/p/3574906.html