一、背景
.NET将Web网站中文件上传将文件存储到FTP文件服务器。
二、文件上传FTP代码实现
2.1 FTP文件上传帮助类
- 文件上传、创建文件夹(多级目录)、文件夹下文件数据统计、文件删除
using Happ.Framework.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
public class FtpHelper
{
/// <summary>
/// 文件上传
/// </summary>
/// <param name="ftpServer"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="localFilePath"></param>
/// <param name="remoteFolderPath"></param>
/// <returns></returns>
public CommonResult UploadFileWithCreateDirectory(string ftpServer, string username, string password, string localFilePath, string remoteFolderPath)
{
CommonResult result = new CommonResult();
// 创建FTP请求检查目录是否存在
var checkDirRequest = (FtpWebRequest)WebRequest.Create($"ftp://{ftpServer}/{remoteFolderPath}");
checkDirRequest.Method = WebRequestMethods.Ftp.ListDirectory;
checkDirRequest.Credentials = new NetworkCredential(username, password);
try
{
using (var checkDirResponse = (FtpWebResponse)checkDirRequest.GetResponse())
{
// 目录存在
Console.WriteLine("目录已存在: " + remoteFolderPath);
}
}
catch (WebException ex)
{
// 如果发生WebException,并且状态码表示目录不存在,则创建目录
if (ex.Response is FtpWebResponse ftpResponse && ftpResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
CreateFtpDirectory(ftpServer, username, password, remoteFolderPath);
Console.WriteLine("目录已创建: " + remoteFolderPath);
}
else
{
throw ex; // 重新抛出异常,可能是其他类型的错误
}
}
// 上传文件
result = UploadFile(ftpServer, username, password, localFilePath, remoteFolderPath);
return result;
}
/// <summary>
/// 创建FTP服务器文件夹--单级目录
/// </summary>
/// <param name="ftpServer"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="remoteFolderPath"></param>
private static void CreateFtpDirectory(string ftpServer, string username, string password, string remoteFolderPath)
{
var createDirRequest = (FtpWebRequest)WebRequest.Create($"ftp://{ftpServer}/{remoteFolderPath}");
createDirRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
createDirRequest.Credentials = new NetworkCredential(username, password);
using (var createDirResponse = (FtpWebResponse)createDirRequest.GetResponse())
{
Console.WriteLine("目录创建成功: " + remoteFolderPath);
}
}
/// <summary>
/// 创建文件夹:支持创建多层
/// </summary>
/// <param name="dirName"></param>
public void CreateFtpDirectorys(string ftpServer, string username, string password, string remoteFolderPath)
{
FtpWebRequest reqFTP;
try
{
// dirName = name of the directory to create
String[] realPath = remoteFolderPath.Split('/');
string currentPath = "/";
foreach (String path in realPath)
{
if (string.IsNullOrEmpty(path) == false)
{
currentPath += $"{path}/";
if (!DirectoryExists(ftpServer, username, password, path))
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create($"ftp://{ftpServer}/{currentPath}");
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(username, password);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
}
}
}
catch (Exception ex)
{
throw new Exception("FtpHelper MakeDir Error --> " + ex.Message);
}
}
/// <summary>
/// 文件上传
/// </summary>
/// <param name="ftpServer"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="localFilePath"></param>
/// <param name="remoteFolderPath"></param>
/// <returns></returns>
public CommonResult UploadFile(string ftpServer, string username, string password, string localFilePath, string remoteFolderPath)
{
CommonResult result = new CommonResult();
result.Success = false;
var uploadRequest = (FtpWebRequest)WebRequest.Create($"ftp://{ftpServer}/{remoteFolderPath}{Path.GetFileName(localFilePath)}");
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
uploadRequest.Credentials = new NetworkCredential(username, password);
uploadRequest.UseBinary = true;
using (var localFileStream = File.OpenRead(localFilePath))
using (var uploadRequestStream = uploadRequest.GetRequestStream())
{
localFileStream.CopyTo(uploadRequestStream);
}
using (var uploadResponse = (FtpWebResponse)uploadRequest.GetResponse())
{
result.Success = true;
//Console.WriteLine("文件上传成功: " + localFilePath + " -> " + remoteFolderPath);
}
return result;
}
/// <summary>
/// 获取Ftp远程文件的文件数量
/// </summary>
/// <param name="ftpServer"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="localFilePath"></param>
/// <param name="remoteFolderPath"></param>
/// <returns></returns>
public List<string> GetFileNames(string ftpServer, string username, string password, string remoteFolderPath)
{
// 创建FTP请求
var request = (FtpWebRequest)WebRequest.Create($"ftp://{ftpServer}/{remoteFolderPath}");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(username, password);
List<string> fileNames = new List<string>();
try
{
// 发送请求并获取响应
using (var response = (FtpWebResponse)request.GetResponse())
{
// 获取响应流并创建StreamReader
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
// 读取每一行
string line;
while ((line = reader.ReadLine()) != null)
{
// 每行代表一个文件或目录,但我们需要的是文件数,所以忽略目录
if (!line.EndsWith("/"))
{
string[] parts = line.Split(' ');
string fileName = parts[parts.Length - 1];
fileNames.Add(fileName);
}
}
//Console.WriteLine($"总共有 {fileNames.Count} 个文件");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return fileNames;
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="ftpServer"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="fileNames"></param>
/// <param name="remoteFolderPath"></param>
/// <returns></returns>
public bool DeleteFile(string ftpServer, string username, string password, string[] fileNames, string remoteFolderPath)
{
bool result = false;
try
{
foreach (string fileName in fileNames)
{
// 创建一个新的FTP请求
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + ftpServer + remoteFolderPath + "/" + fileName));
// 设置请求的认证信息
request.Credentials = new NetworkCredential(username, password);
// 设置请求的方法为DELE,表示删除文件
request.Method = WebRequestMethods.Ftp.DeleteFile;
// 发送请求
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
// 关闭响应流和请求
response.Close();
request.Abort();
}
result = true;
}
catch (Exception ex)
{
throw;
}
return result;
}
}
2.2 返回结果实体(可自定义)
public class CommonResult
{
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
public string Data4 { get; set; }
public object Data5 { get; set; }
public bool Cancel { get; set; }
public CommonResult()
: this(null)
{
}
public CommonResult(string errorMessage)
{
ErrorMessage = errorMessage;
Cancel = false;
}
public void CopyValue(CommonResult result)
{
Cancel = result.Cancel;
Data1 = result.Data1;
Data2 = result.Data2;
Data3 = result.Data3;
Data4 = result.Data4;
Data5 = result.Data5;
Success = result.Success;
ErrorMessage = result.ErrorMessage;
}
}
2.3 FTP文件上传测试
[TestMethod]
public void TestFtpFile()
{
string ftpServer = "192.xx.xx.xx";
string username = "FTP-User";
string password = "*****";
string localFilePath = "E:\\测试报告.xls";
string fileName = "测试报告.xls";
string remoteFolderPath = @"/dev/";
//1/文件上传
var res = new FtpHelper().UploadFileWithCreateDirectory(ftpServer, username, password, localFilePath, remoteFolderPath);
//2.文件夹下文件数量获取
string[] filesNames = new FtpHelper().GetFileNames(ftpServer, username, password, remoteFolderPath).ToArray();
//3、删除文件
var resdel = new FtpHelper().DeleteFile(ftpServer, username, password, filesNames, remoteFolderPath);
}