最近因为要用到ftp,用于文件上传,所以学习了一番。
总结代码如下,以备后续遗忘了可以再看下,部分方法。
1.基本字段
private string _userName;
public string UserName { get { return _userName; } set { _userName = value; } }
private string _password;
public string Password { get { return _password; } set { _password = value; } }
//private int _port;
//public int Port { get { return _port; } set { _port = value; } }
private string _remotePath;
public string RemotePath { get { return _remotePath; } set { _remotePath = value; } }
private string _host;
public string Host
{
get { return _host; }
set
{
//需要判定格式: 是否带有ftp
_host = value.ToLower().StartsWith("ftp://") ? value : "ftp://" + value;
_host = _host + "/";
}
}
private bool _usePASV = true;
public bool UsePASV { get { return _usePASV; } set { _usePASV = value; } }
2. 构造函数
public FtpHelper(string host, string userName, string password)
{
UserName = userName;
Password = password;
//Port = port; //可能不需要使用
Host = host;
}
3. 基本连接创建
/// <summary>
/// ftp根路径(Host+RmotePath)
/// </summary>
/// <returns></returns>
private string GetRemotePathRoot()
{
if (!string.IsNullOrEmpty(RemotePath))
return Path.Combine(new string[] { Host, RemotePath });
return Host;
}
/// <summary>
/// 获取文件路径
/// </summary>
/// <param name="fileName">文件名(eg: 1.txt)</param>
/// <returns></returns>
private string GetUri(string fileName)
{
string uri = GetRemotePathRoot();
return Path.Combine(new string[] { uri, fileName });
}
/// <summary>
/// 创建Ftp请求实例
/// </summary>
/// <param name="uri"></param>
/// <param name="method">upload/delete/....</param>
/// <returns></returns>
private FtpWebRequest CreateFtpWebRequest(string uri, string method)
{
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(uri);
request.Credentials = new NetworkCredential(UserName, Password);
//本次传输完成后断开连接
request.KeepAlive = false;
request.Method = method;
request.UseBinary = true;
request.UsePassive = UsePASV;
return request;
}
4.上传文件
/// <summary>
/// 上传单个文件
/// </summary>
/// <param name="filePath">本地文件路径</param>
/// <returns>true/false</returns>
public bool Upload(string localFilePath)
{
bool result = false;
FileInfo file = new FileInfo(localFilePath);
FtpWebRequest ftpRequest;
string uri;
//1.本地文件不存在,返回false
if (!file.Exists) throw new Exception("本地文件不存在!路径:" + localFilePath);
//2.获取ftp连接
uri = GetUri(file.Name);
ftpRequest = CreateFtpWebRequest(uri, WebRequestMethods.Ftp.UploadFile);
//3.缓冲区设定
int buffSize = 1024;
byte[] buffer = new byte[buffSize];
//4.上传数据
using (FileStream fs = file.OpenRead())
{
using (Stream remoteWriteStream = ftpRequest.GetRequestStream())
{
//开始读入数据
int length = fs.Read(buffer, 0, buffSize);
while (length != 0)
{
//写入远程数据流
remoteWriteStream.Write(buffer, 0, buffSize);
length = fs.Read(buffer, 0, buffSize);
}
result = true;
}
}
return result;
}
5.批量上传,在上传基础上实现
public void BatchUpload(string folder, string fileNameMask)
{
string[] files = Directory.GetFiles(folder, fileNameMask);
foreach (string file in files)
{
Upload(file);
}
}
6.下载(没有续传功能)
/// <summary>
/// 下载ftp服务器文件(不支持断点续传)
/// </summary>
/// <param name="fileName">文件名(*.txt)</param>
/// <param name="localPath">保存路径</param>
/// <returns></returns>
public bool Download(string fileName,string localPath,string newFileName="") {
bool result = false;
newFileName = (newFileName == "") ? fileName : newFileName;
string localFilePath = Path.Combine(new string[] { localPath, newFileName });
string uri = GetUri(fileName);
using (FileStream fs = new FileStream(localFilePath, FileMode.OpenOrCreate))
{
FtpWebRequest request = CreateFtpWebRequest(uri, WebRequestMethods.Ftp.DownloadFile);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) {
//定位到本地文件的末尾写入
fs.Position = fs.Length;
//分配2k的缓冲区域
byte[] buffer = new byte[2048];
using (Stream serverWriteStream = response.GetResponseStream())
{
int size = serverWriteStream.Read(buffer, 0, buffer.Length);
while (size > 0)
{
//本地文件数据流写入
fs.Write(buffer, 0, size);
size = serverWriteStream.Read(buffer, 0, buffer.Length);
}
}
}
result = true;
}
return result;
}
7.获取文件夹列表,主要是 WebRequestMethods.Ftp.ListDirectoryDetails
public List<string> GetFileList(string DirName = "")
{
List<string> result = new List<string>();
string uri = (DirName == "") ? GetRemotePathRoot() : Path.Combine(new string[] { GetRemotePathRoot(), DirName });
FtpWebRequest request = CreateFtpWebRequest(uri, WebRequestMethods.Ftp.ListDirectoryDetails);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
{
string fileName = reader.ReadLine();
while (fileName != null)
{
if (!fileName.Trim().ToLower().Contains("<dir>"))
result.Add(fileName.Substring(39).Trim());
fileName = reader.ReadLine();
}
}
}
return result;
}
为啥呢?为啥要截取第39个字符开始的位置, ftp响应文件如此?默默不说(百度的...)。。。。。。。