using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace BaseLibComm
{
public class FtpClient
{
#region 构造函数
///
/// 创建FTP工具
///
/// 默认不使用SSL,使用二进制传输方式,使用被动模式
///
///
/// 主机名称
/// 用户名
/// 密码
public FtpClient(string host, string userId, string password)
: this(host, userId, password, 21, null, false, true, true)
{
}
///
/// 创建FTP工具
///
/// 主机名称
/// 用户名
/// 密码
/// 端口
/// 允许Ssl
/// 代理
/// 允许二进制
/// 允许被动模式
public FtpClient(string host, string userId, string password, int port, IWebProxy proxy, bool enableSsl, bool useBinary, bool usePassive)
{
this.UserId = userId;
this.Password = password;
if (host.ToLower().StartsWith("ftp://"))
{
this.host = host;
}
else
{
this.host = "ftp://" + host;
}
this.Port = port;
this.Proxy = proxy;
this.EnableSsl = enableSsl;
this.UseBinary = useBinary;
this.UsePassive = usePassive;
}
#endregion
#region Property
private string host = string.Empty;
public string Host
{
get
{
return this.host ?? string.Empty;
}
}
public string UserId { get; } = string.Empty;// 登录用户名
public string Password { get; } = string.Empty;// 密码
public IWebProxy Proxy { get; set; } = null;// 代理
public int Port { get; set; } = 21;// 端口
public bool EnableSsl { get; } = false;// EnableSsl 设置是否允许Ssl
public bool UsePassive { get; set; } = true;// 被动模式 使用被动模式
public bool UseBinary { get; set; } = true;// 二进制方式
private string remotePath = "/";
public string RemotePath //返回FTP服务器上的当前路径(可以是 / 或 /a/../ 的形式)
{
get
{
return remotePath;
}
set
{
string result = "/";
if (!string.IsNullOrEmpty(value) && value != "/")
{
result = "/" + value.TrimStart('/').TrimEnd('/') + "/";
}
this.remotePath = result;
}
}
#endregion
#region 创建一个FTP连接
///
/// 创建一个FTP请求
///
/// 请求地址
/// 请求方法
/// FTP请求
private FtpWebRequest CreateRequest(string url, string method)
{
//建立连接
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential(UserId, Password);
request.Proxy = Proxy;
request.KeepAlive = false;//命令执行完毕之后关闭连接
request.UseBinary = UseBinary;
request.UsePassive = UsePassive;
request.EnableSsl = EnableSsl;
request.Method = method;
return request;
}
#endregion
#region 上传一个文件到远端路径下
///
/// 把文件上传到FTP服务器的RemotePath下
///
/// 本地文件信息
/// 要保存到FTP文件服务器上的名称
public bool Upload(FileInfo localFile, string remoteFileName)
{
bool result = false;
if (localFile.Exists)
{
string url = Host.TrimEnd('/') + RemotePath + remoteFileName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.UploadFile);
//上传数据
using (Stream rs = request.GetRequestStream())
using (FileStream fs = localFile.OpenRead())
{
byte[] buffer = new byte[4096];//4K
int count = fs.Read(buffer, 0, buffer.Length);
while (count > 0)
{
rs.Write(buffer, 0, count);
count = fs.Read(buffer, 0, buffer.Length);
}
fs.Close();
result = true;
}
return result;
}
throw new Exception(string.Format("本地文件不存在,文件路径:{0}", localFile.FullName));
}
#endregion
#region 从FTP服务器上下载文件
///
/// 从当前目录下下载文件
///
/// 如果本地文件存在,则从本地文件结束的位置开始下载.
///
///
/// 服务器上的文件名称
/// 本地文件名称
/// 返回一个值,指示是否下载成功
public bool Download(string serverName, string localName)
{
bool result = false;
using (FileStream fs = new FileStream(localName, FileMode.OpenOrCreate)) //创建或打开本地文件
{
//建立连接
string url = Host.TrimEnd('/') + RemotePath + serverName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.DownloadFile);
request.ContentOffset = fs.Length;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
fs.Position = fs.Length;
byte[] buffer = new byte[4096];//4K
int count = response.GetResponseStream().Read(buffer, 0, buffer.Length);
while (count > 0)
{
fs.Write(buffer, 0, count);
count = response.GetResponseStream().Read(buffer, 0, buffer.Length);
}
response.GetResponseStream().Close();
}
result = true;
}
return result;
}
#endregion
#region 重命名FTP服务器上的文件
///
/// 文件更名
///
/// 原文件名
/// 新文件名
/// 返回一个值,指示更名是否成功
public bool Rename(string oldFileName, string newFileName)
{
bool result = false;
//建立连接
string url = Host.TrimEnd('/') + RemotePath + oldFileName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.Rename);
request.RenameTo = newFileName;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result = true;
}
return result;
}
#endregion
#region 从当前目录下获取文件列表
///
/// 获取当前目录下文件列表
///
///
public List GetFileList()
{
List result = new List();
//建立连接
string url = Host.TrimEnd('/') + RemotePath;//string url = (Host +":"+ Port).TrimEnd('/') + RemotePath;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.ListDirectory);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名
string line = reader.ReadLine();
while (line != null)
{
result.Add(line);
line = reader.ReadLine();
}
}
return result;
}
#endregion
#region 从FTP服务器上获取文件和文件夹列表
///
/// 获取详细列表 从FTP服务器上获取文件和文件夹列表
///
///
public List GetFileDetails()
{
List result = new List();
//建立连接
string url = Host.TrimEnd('/') + RemotePath;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.ListDirectoryDetails);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);//中文文件名
string line = reader.ReadLine();
while (line != null)
{
result.Add(line);
line = reader.ReadLine();
}
}
return result;
}
#endregion
#region 从FTP服务器上删除文件
///
/// 删除FTP服务器上的文件
///
/// 文件名称
/// 返回一个值,指示是否删除成功
public bool DeleteFile(string fileName)
{
bool result = false;
//建立连接
string url = Host.TrimEnd('/') + RemotePath + fileName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.DeleteFile);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result = true;
}
return result;
}
#endregion
#region 在FTP服务器上创建目录
///
/// 在当前目录下创建文件夹
///
/// 文件夹名称
/// 返回一个值,指示是否创建成功
public bool MakeDirectory(string dirName)
{
bool result = false;
//建立连接
string url = Host.TrimEnd('/') + RemotePath + dirName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.MakeDirectory);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result = true;
}
return result;
}
#endregion
#region 从FTP服务器上删除目录
///
/// 删除文件夹
///
/// 文件夹名称
/// 返回一个值,指示是否删除成功
public bool DeleteDirectory(string dirName)
{
bool result = false;
//建立连接
string url = Host.TrimEnd('/') + RemotePath + dirName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.RemoveDirectory);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result = true;
}
return result;
}
#endregion
#region 从FTP服务器上获取文件大小
///
/// 获取文件大小
///
///
///
public long GetFileSize(string fileName)
{
long result = 0;
//建立连接
string url = Host.TrimEnd('/') + RemotePath + fileName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.GetFileSize);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result = response.ContentLength;
}
return result;
}
#endregion
#region 给FTP服务器上的文件追加内容
///
/// 给FTP服务器上的文件追加内容
///
/// 本地文件
/// FTP服务器上的文件
/// 返回一个值,指示是否追加成功
public bool Append(FileInfo localFile, string remoteFileName)
{
if (localFile.Exists)
{
using (FileStream fs = new FileStream(localFile.FullName, FileMode.Open))
{
return Append(fs, remoteFileName);
}
}
throw new Exception(string.Format("本地文件不存在,文件路径:{0}", localFile.FullName));
}
///
/// 给FTP服务器上的文件追加内容
///
/// 数据流(可通过设置偏移来实现从特定位置开始上传)
/// FTP服务器上的文件
/// 返回一个值,指示是否追加成功
public bool Append(Stream stream, string remoteFileName)
{
bool result = false;
if (stream != null && stream.CanRead)
{
//建立连接
string url = Host.TrimEnd('/') + RemotePath + remoteFileName;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.AppendFile);
using (Stream rs = request.GetRequestStream())
{
//上传数据
byte[] buffer = new byte[4096];//4K
int count = stream.Read(buffer, 0, buffer.Length);
while (count > 0)
{
rs.Write(buffer, 0, count);
count = stream.Read(buffer, 0, buffer.Length);
}
result = true;
}
}
return result;
}
#endregion
#region 获取FTP服务器上的当前路径
///
/// 获取FTP服务器上的当前路径
///
public string CurrentDirectory
{
get
{
string result = string.Empty;
string url = Host.TrimEnd('/') + RemotePath;
FtpWebRequest request = CreateRequest(url, WebRequestMethods.Ftp.PrintWorkingDirectory);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
string temp = response.StatusDescription;
int start = temp.IndexOf('"') + 1;
int end = temp.LastIndexOf('"');
if (end >= start)
{
result = temp.Substring(start, end - start);
}
}
return result;
}
}
#endregion
#region 检查当前路径上是否存在某个文件
///
/// 检查文件是否存在
///
/// 要检查的文件名
/// 返回一个值,指示要检查的文件是否存在
public bool CheckFileExist(string fileName)
{
bool result = false;
if (fileName != null && fileName.Trim().Length > 0)
{
fileName = fileName.Trim();
List files = GetFileList();
if (files != null && files.Count > 0)
{
foreach (string file in files)
{
if (file.ToLower() == fileName.ToLower())
{
result = true;
break;
}
}
}
}
return result;
}
#endregion
}
}