两种实现方式:
(1)系统方法手动实现
优点:不依靠其他任何依赖,可以实现自己需要的各种自定需求的操作
缺点:手动实现起来麻烦,操作繁琐,自己实现需要考虑各种异常情况等等
(2)Nuget包FluentFTP
优点:实现起来简单,使用起来方便,功能丰富
缺点:必须要添加项目依赖Nuget包FluentFTP
1、系统方法手动实现
csharp
/// <summary>
/// ftp传输
/// </summary>
/// <param name="ftpSavePath">ftp保存地址 例:ftp://172.18.18.53/172.18.18.101/</param>
/// <param name="ftpFileName">ftp保存文件名称 例:htrs_1.mp4</param>
/// <param name="localFilePath">本地文件路径 例:C:\\files\\htrs_1.mp4</param>
/// <param name="userName">ftp用户名</param>
/// <param name="password">ftp密码</param>
public static bool FTPUploadFile(string ftpSavePath, string ftpFileName, string localFilePath, string userName, string password)
{
if (!File.Exists(localFilePath))
{
return false;
}
//校验路径是否存在
if (!TryCreateDirectory(ftpSavePath, userName, password))
return false;
try
{
FileInfo fileInfo = new FileInfo(localFilePath);
// 创建ftp请求
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpSavePath + ftpFileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(userName, password);
request.UseBinary = true;
request.KeepAlive = false; // 上传完成后关闭连接
request.Timeout = 300000; // 5分钟超时
// ✅ 使用流式传输,避免内存溢出
using (FileStream fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))
using (Stream requestStream = request.GetRequestStream())
{
byte[] buffer = new byte[128 * 1024]; // 64KB缓冲区
int bytesRead;
long totalBytes = 0;
DateTime lastLogTime = DateTime.Now;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
// 每10秒记录一次上传进度(可选)
if ((DateTime.Now - lastLogTime).TotalSeconds >= 10)
{
double progress = (double)totalBytes / fileInfo.Length * 100;
lastLogTime = DateTime.Now;
}
}
}
}
catch (Exception ex)
{
return false;
}
return true;
}
/// <summary>
/// 校验ftp目录是否存在
/// </summary>
/// <param name="directoryUri"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
public static bool TryCreateDirectory(string directoryUri, string username, string password)
{
try
{
// 创建 FTP 请求以检查目录
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(directoryUri);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(username, password);
// 尝试获取目录列表
using FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
// 如果目录不存在,则会抛出异常
if (ex.Response is FtpWebResponse response && response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
// 创建目录
FtpWebRequest createDirRequest = (FtpWebRequest)WebRequest.Create(directoryUri);
createDirRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
createDirRequest.Credentials = new NetworkCredential(username, password);
using var createResponse = (FtpWebResponse)createDirRequest.GetResponse();
}
else
{
//其他异常
return false;
}
}
catch (Exception ex)
{
return false;
}
return true;
}
2、使用开源的Nuget包FluentFTP
csharp
public async Task Test()
{
string ip = "172.18.18.200";
int port = 21;
string userName = "ftpuser";
string pwd = "ftpuser";
FluentFTP.AsyncFtpClient ftp = new FluentFTP.AsyncFtpClient(ip, userName, pwd, port)
{
Config = new FluentFTP.FtpConfig
{
ConnectTimeout = 5000, //连接超时,单位为毫秒
DataConnectionConnectTimeout = 5000, //数据连接超时,单位为毫秒
DataConnectionReadTimeout = 5000, //数据读取超时,单位为毫秒
ReadTimeout = 5000, //读取超时,单位为毫秒
RetryAttempts = 3 //重试次数
}
};
//开始连接FTP服务器
await ftp.Connect();
// 检查目录是否存在,如果不存在则创建
if (! await ftp.DirectoryExists("wtTest"))
{
await ftp.CreateDirectory("wtTest");
}
// 上传文件
await ftp.UploadFile(@"C:\Users\Htkw\Desktop\111\1.jpg", "wtTest/test.jpg");
// 下载文件
await ftp.DownloadFile(@"C:\Users\Htkw\Desktop\111\downloaded_test.jpg", "wtTest/test.jpg");
await ftp.Disconnect(); //关闭连接
await ftp.DisposeAsync(); //释放资源
}