代码:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
internal class FTPManager : Singleton<FTPManager>
{
/// <summary>
/// FTP 地址
/// </summary>
public string FtpUrl { get; set; }
/// <summary>
/// FTP 用户名
/// </summary>
public string FtpUser { get; set; }
/// <summary>
/// FTP 密码
/// </summary>
public string FtpPassword { get; set; }
/// <summary>
/// FTP 文件夹列表
/// </summary>
public List<string> FtpDirectoryList { get; private set; } = new List<string>();
/// <summary>
/// FTP 文件列表
/// </summary>
public List<FileInfo1> FtpFileList { get; private set; } = new List<FileInfo1>();
/// <summary>
/// 文件夹列表(临时)
/// </summary>
private Queue<string> DirectoryListTemporary { get; set; } = new Queue<string>();
/// <summary>
/// 读取文件
/// </summary>
public void Read()
{
if (string.IsNullOrEmpty(FtpUrl))
{
Console.WriteLine("请先读取配置文件");
return;
}
Console.WriteLine("[GetAllFileList]开始读取 FTP 文件");
FtpFileList.Clear();
FtpDirectoryList.Clear();
DirectoryListTemporary.Clear();
GetFtpDirectoryList(FtpUrl);
Console.WriteLine("[GetAllFileList]读取 FTP 文件完成");
}
/// <summary>
/// 获取所有文件,文件夹,文件大小,修改时间,哈希值
/// </summary>
/// <param name="remoteFolderPath"></param>
public void GetFtpDirectoryList(string url)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(FtpUser, FtpPassword);
request.KeepAlive = true;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line == null) continue;
string[] parts = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
//注意:FTP 获取的时间中并没有秒数部分
//适用与 Microsoft IIS FTP 服务器,返回格式如下
//文件 "06-10-23 02:57PM 222720 CNCMain.exe"
//文件夹 "06-14-23 09:17AM <DIR> bin"
if (parts.Length == 4)
{
//文件夹
if (parts[2].Contains("<DIR>"))
{
string directoryName = line.Substring(line.LastIndexOf("<DIR>") + 5).Trim();
string path = $"{url}{directoryName}//";
FtpDirectoryList.Add(path);
DirectoryListTemporary.Enqueue(path);
}
//文件
else
{
string path = $"{url}{parts[3]}";
Console.WriteLine("正在读取:{0}", path);
long size = 0;
long.TryParse(parts[2], out size);
DateTime lastModified = DateTime.MinValue;
string dateString = string.Join(" ", parts[5], parts[6], parts[7]);
DateTime.TryParse(dateString, out lastModified);
var ftpFile = new FileInfo1();
ftpFile.Size = size;
ftpFile.FileName = parts[3];
ftpFile.FilePath = path;
ftpFile.LastWriteTime = lastModified;
FtpFileList.Add(ftpFile);
}
}
//适用于 UNIX/Linux FTP 服务器,格式如下
//文件 -rw-r--r-- 1 ftp ftp 17172 Apr 29 16:12 lang.txt
//文件夹 drwxr-xr-x 1 ftp ftp 0 Jun 17 10:46 Test1
else if (parts.Length == 9)
{
string permission = parts[0];
//文件夹
if (permission.StartsWith("d"))
{
string directoryName = parts[8];
string path = $"{url}{directoryName}//";
FtpDirectoryList.Add(path);
DirectoryListTemporary.Enqueue(path);
}
//文件
else if (permission.StartsWith("-"))
{
string path = $"{url}{parts[8]}";
Console.WriteLine("正在读取:{0}", path);
long size = 0;
long.TryParse(parts[4], out size);
string datePart = string.Join(" ", parts[5], parts[6], parts[7]);
DateTime lastWriteTime = DateTime.MinValue;
if (parts[7].Contains(":"))
{
//日期格式:Jun 17 10:46
lastWriteTime = DateTime.ParseExact(datePart, "MMM dd HH:mm", CultureInfo.InvariantCulture);
}
else
{
//如果是去年的文件,则为:Nov 16 2023
lastWriteTime = DateTime.ParseExact(datePart, "MMM dd yyyy", CultureInfo.InvariantCulture);
}
var ftpFile = new FileInfo1();
ftpFile.Size = size;
ftpFile.FileName = parts[8];
ftpFile.FilePath = path;
ftpFile.LastWriteTime = lastWriteTime;
FtpFileList.Add(ftpFile);
}
}
}
}
if (DirectoryListTemporary.Count > 0)
GetFtpDirectoryList(DirectoryListTemporary.Dequeue());
}
catch (Exception ex)
{
Console.WriteLine("读取 FTP 文件列表错误:{0}", ex.Message);
}
}
}
end