You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中获取FTP近期上传文件并触发通知?

解决C#中FTP新增文件检测的失效问题

这个问题确实挺棘手的——依赖文件最后修改时间判断新增文件,碰到那些本身修改时间是旧的文件就完全失效了。我结合自己的实战经验给你几个可行的解决思路:

方案1:利用FTP服务器的MLSD命令获取文件上传时间

很多现代FTP服务器(比如IIS、vsftpd)支持MLSD命令,该命令返回的文件信息里通常包含上传/创建时间字段(区别于文件本身的修改时间)。你可以通过FtpWebRequest发送这个命令并解析结果:

var request = (FtpWebRequest)WebRequest.Create("ftp://your-ftp-server/target-path");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential("your-username", "your-password");

using (var response = (FtpWebResponse)request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        // MLSD返回格式示例:modify=20240520143000;perm=adfrw;size=4096; example.txt
        if (line.Contains("modify=") && !string.IsNullOrEmpty(line.Split(';').Last()))
        {
            var timeSegment = line.Split(';').First(p => p.StartsWith("modify=")).Split('=')[1];
            if (DateTime.TryParseExact(timeSegment, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime uploadTime))
            {
                if (uploadTime >= DateTime.Now.AddMinutes(-5))
                {
                    var fileName = line.Split(';').Last().Trim();
                    // 触发新增文件通知逻辑
                    Console.WriteLine($"检测到近期上传文件:{fileName}");
                }
            }
        }
    }
}

注意:不同FTP服务器的MLSD返回格式可能略有差异,需要根据实际返回内容调整解析逻辑。如果服务器不支持MLSD,这个方法无法使用。

方案2:用WinSCP跟踪文件列表变化(最推荐)

你已经在使用WinSCP,其实它的.NET Assembly内置了文件变更对比功能——通过记录上次扫描的文件列表,下次对比时直接找出新增文件,完全不依赖文件本身的修改时间:

SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "your-ftp-server",
    UserName = "your-username",
    Password = "your-password"
};

// 用于存储上次扫描的文件列表(可持久化到本地文件/数据库,避免程序重启后丢失)
Dictionary<string, DateTime> lastScannedFiles = new Dictionary<string, DateTime>();

using (Session session = new Session())
{
    session.Open(sessionOptions);
    // 初始化第一次扫描的文件列表
    var initialDir = session.ListDirectory("/target-path");
    foreach (var file in initialDir.Files)
    {
        if (!file.IsDirectory)
        {
            lastScannedFiles[file.Name] = file.LastWriteTime;
        }
    }

    // 定时扫描(示例为每5分钟一次)
    while (true)
    {
        Thread.Sleep(TimeSpan.FromMinutes(5));
        var currentDir = session.ListDirectory("/target-path");
        var currentFiles = currentDir.Files.Where(f => !f.IsDirectory).ToDictionary(f => f.Name, f => f.LastWriteTime);

        // 找出新增文件:当前列表有但上次列表没有的文件
        var newFiles = currentFiles.Keys.Except(lastScannedFiles.Keys);
        foreach (var fileName in newFiles)
        {
            // 触发通知逻辑
            Console.WriteLine($"检测到新增文件:{fileName}");
        }

        // 更新扫描记录
        lastScannedFiles = currentFiles;
    }
}

这个方案的优势是兼容性强,WinSCP会自动处理不同FTP服务器的差异,而且彻底解决了文件修改时间不准确的问题,上手成本也低(因为你已经熟悉WinSCP)。

方案3:读取FTP服务器的上传日志

如果你的FTP服务器允许开启上传日志(比如IIS的FTP日志、vsftpd的xferlog),可以让服务器记录每次上传操作的详细信息(包括文件名、上传时间、客户端信息等)。你的C#程序可以定期读取日志文件,解析出近期的上传记录来识别新增文件。

这个方法需要你有服务器配置权限,好处是能精准获取上传时间,但需要维护日志的读取和解析逻辑,还要考虑日志滚动、权限等问题。

方案4:修改FTP服务器的上传逻辑(仅限自有服务器)

如果FTP服务器是你自己管理的,可以在服务器端添加脚本(Windows批处理/Linux Shell脚本),当文件上传完成后,强制将文件的最后修改时间更新为当前上传时间。这样你原来基于修改时间的检测逻辑就能正常工作了。

内容的提问来源于stack exchange,提问作者Narendra Jangir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:02:13