C# 在ASP.NET/C中监视FTP目录
我有一个本地目录的文件系统监视程序。很好用。我想为FTP实现同样的功能。我有什么办法可以做到吗?我检查了许多解决方案,但不清楚 逻辑:希望在某个时间戳之后从FTP获取文件。 面临的问题:从FTP获取所有文件,然后过滤结果会影响使用FtpWebRequest的性能 有什么正确的方法吗?WinSCP正在等待。我现在不能用它C# 在ASP.NET/C中监视FTP目录,c#,.net,ftp,filesystemwatcher,ftpwebrequest,C#,.net,Ftp,Filesystemwatcher,Ftpwebrequest,我有一个本地目录的文件系统监视程序。很好用。我想为FTP实现同样的功能。我有什么办法可以做到吗?我检查了许多解决方案,但不清楚 逻辑:希望在某个时间戳之后从FTP获取文件。 面临的问题:从FTP获取所有文件,然后过滤结果会影响使用FtpWebRequest的性能 有什么正确的方法吗?WinSCP正在等待。我现在不能用它 FileSystemWatcher oFsWatcher = new FileSystemWatcher(); OFSWatchers.Add(oFsWatcher); oFsW
FileSystemWatcher oFsWatcher = new FileSystemWatcher();
OFSWatchers.Add(oFsWatcher);
oFsWatcher.Path = sFilePath;
oFsWatcher.Filter = string.IsNullOrWhiteSpace(sFileFilter) ? "*.*" : sFileFilter;
oFsWatcher.NotifyFilter = NotifyFilters.FileName;
oFsWatcher.EnableRaisingEvents = true;
oFsWatcher.IncludeSubdirectories = bIncludeSubdirectories;
oFsWatcher.Created += new FileSystemEventHandler(OFsWatcher_Created);
除非您可以访问承载服务的操作系统;这会有点困难 在文件系统上放置一个钩子,一旦出现问题,它将立即通知应用程序 没有这样的钩子。除此之外,它总是由客户发起的 因此,要实现这样的逻辑,您应该定期执行NLST来列出FTP目录内容并跟踪更改或散列,可能是您自己执行的MDTM 更多信息:
除非您可以访问承载服务的操作系统;这会有点困难 在文件系统上放置一个钩子,一旦出现问题,它将立即通知应用程序 没有这样的钩子。除此之外,它总是由客户发起的 因此,要实现这样的逻辑,您应该定期执行NLST来列出FTP目录内容并跟踪更改或散列,可能是您自己执行的MDTM 更多信息: 您不能使用或任何其他方式,因为FTP协议没有任何API来通知客户端远程目录中的更改 您所能做的就是定期迭代远程树并查找更改 如果您使用支持远程树递归列表的FTP客户端库,那么它实际上相当容易实现。不幸的是,内置的.NET FTP客户端没有。但例如,对于,您可以使用 见文章: 这将更新甚至修改过的文件,而不仅仅是新文件 尽管从web应用程序使用WinSCP.NET程序集可能会有问题。如果您不想使用第三方库,则必须考虑FtpWebRequest的限制。有关如何使用FtpWebRequest递归列出远程目录树的示例,请参阅我的答案 您编辑了您的问题,表示您对我建议的解决方案存在性能问题。尽管您已经提出了一个新问题,其中包括: 您不能使用或任何其他方式,因为FTP协议没有任何API来通知客户端远程目录中的更改 您所能做的就是定期迭代远程树并查找更改 如果您使用支持远程树递归列表的FTP客户端库,那么它实际上相当容易实现。不幸的是,内置的.NET FTP客户端没有。但例如,对于,您可以使用 见文章: 这将更新甚至修改过的文件,而不仅仅是新文件 尽管从web应用程序使用WinSCP.NET程序集可能会有问题。如果您不想使用第三方库,则必须考虑FtpWebRequest的限制。有关如何使用FtpWebRequest递归列出远程目录树的示例,请参阅我的答案 您编辑了您的问题,表示您对我建议的解决方案存在性能问题。尽管您已经提出了一个新问题,其中包括: 我有一个替代方案来实现我的功能 说明: 我正在下载文件从FTP读取权限要求。具有相同的文件夹结构 <> p>所以每次作业/服务运行时,我都可以检查物理路径,如果不存在同样的文件完整路径,则可以将其视为一个新文件。我可以做一些同样的动作,也可以下载 这只是另一种解决办法 代码更改: 我有一个替代方案来实现我的功能 说明: 我正在下载文件从FTP读取权限要求。具有相同的文件夹结构 <> p>所以每次作业/服务运行时,我都可以检查物理路径,如果不存在同样的文件完整路径,则可以将其视为一个新文件。我可以做一些同样的动作,也可以下载 这只是另一种解决办法 代码更改:
是的,我知道没有直接的方法。我对filewatcher系统的概念还不熟悉,你能提供更多的细节吗?然后你能展示一些你的FTP代码吗?在没有任何合作的情况下,很难变得更具体。请通过编辑您的问题来实现这一点。我仍在探索,还没有开始为同样的问题编写代码。我已经为本地目录实现了。我知道没有直接的方法。我对filewatcher系统的概念还不熟悉,你能提供更多的细节吗?然后你能展示一些你的FTP代码吗?很难理解
在没有什么可合作的情况下,更具体一些。请通过编辑您的问题来实现这一点。我仍在探索,还没有开始为同样的问题编写代码。我已经为本地目录实现了。FileSystemWatcher对此有何选择?这就是我从一开始就向你提出的建议。你写道,从FTP获取所有文件,然后过滤结果会影响性能。我对FTP功能不熟悉,这就是为什么我感到困惑的原因。一旦我完全理解,我就使用了这个解决方案。我们已经有了流畅的FTP包,这就是为什么没有使用winscp的原因。无论如何,这个解决方案很有帮助。谢谢你的帮助。。通过阅读你的方法,我得到了一些想法。好的,这很有效。当然但这与你的问题相矛盾。关于这一点,有什么选择?这就是我从一开始就向你提出的建议。你写道,从FTP获取所有文件,然后过滤结果会影响性能。我对FTP功能不熟悉,这就是为什么我感到困惑的原因。一旦我完全理解,我就使用了这个解决方案。我们已经有了流畅的FTP包,这就是为什么没有使用winscp的原因。无论如何,这个解决方案很有帮助。谢谢你的帮助。。通过阅读你的方法,我得到了一些想法。好的,这很有效。当然但这与你的问题相矛盾。
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "example.com",
UserName = "user",
Password = "password",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
List<string> prevFiles = null;
while (true)
{
// Collect file list
List<string> files =
session.EnumerateRemoteFiles(
"/remote/path", "*.*", EnumerationOptions.AllDirectories)
.Select(fileInfo => fileInfo.FullName)
.ToList();
if (prevFiles == null)
{
// In the first round, just print number of files found
Console.WriteLine("Found {0} files", files.Count);
}
else
{
// Then look for differences against the previous list
IEnumerable<string> added = files.Except(prevFiles);
if (added.Any())
{
Console.WriteLine("Added files:");
foreach (string path in added)
{
Console.WriteLine(path);
}
}
IEnumerable<string> removed = prevFiles.Except(files);
if (removed.Any())
{
Console.WriteLine("Removed files:");
foreach (string path in removed)
{
Console.WriteLine(path);
}
}
}
prevFiles = files;
Console.WriteLine("Sleeping 10s...");
Thread.Sleep(10000);
}
}
while (true)
{
SynchronizationResult result =
session.SynchronizeDirectories(
SynchronizationMode.Local, "/remote/path", @"C:\local\path", true);
result.Check();
// You can inspect result.Downloads for a list for updated files
Console.WriteLine("Sleeping 10s...");
Thread.Sleep(10000);
}
private static void GetFiles()
{
using (FtpClient conn = new FtpClient())
{
string ftpPath = "ftp://myftp/";
string downloadFileName = @"C:\temp\FTPTest\";
downloadFileName += "\\";
conn.Host = ftpPath;
//conn.Credentials = new NetworkCredential("ftptest", "ftptest");
conn.Connect();
//Get all directories
foreach (FtpListItem item in conn.GetListing(conn.GetWorkingDirectory(),
FtpListOption.Modify | FtpListOption.Recursive))
{
// if this is a file
if (item.Type == FtpFileSystemObjectType.File)
{
string localFilePath = downloadFileName + item.FullName;
//Only newly created files will be downloaded.
if (!File.Exists(localFilePath))
{
conn.DownloadFile(localFilePath, item.FullName);
//Do any action here.
Console.WriteLine(item.FullName);
}
}
}
}
}