Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FileSystemWatcher似乎忽略了文件名中的多个点_C#_Windows_Service_File Watcher - Fatal编程技术网

C# FileSystemWatcher似乎忽略了文件名中的多个点

C# FileSystemWatcher似乎忽略了文件名中的多个点,c#,windows,service,file-watcher,C#,Windows,Service,File Watcher,我有一个C#windows服务在监视一个文件夹。如果文件是使用传统的windows文件名结构创建的,则一切正常,例如foo.zip。但是随之而来的是一个讨厌的unix用户,他给自己的文件命名为foo.bar.11-10-2013.zip 我的程序中的文件监视程序从未看到此文件。没有过滤器集,因此默认设置为*.* 如果我重命名该文件以删除点并用下划线替换它们,则文件观察者会看到该文件 我试着用谷歌搜索答案,但我的另一个问题是我不知道如何陈述这个问题——我们称之为多重延伸、多重点还是多重句点?所有这

我有一个C#windows服务在监视一个文件夹。如果文件是使用传统的windows文件名结构创建的,则一切正常,例如foo.zip。但是随之而来的是一个讨厌的unix用户,他给自己的文件命名为foo.bar.11-10-2013.zip

我的程序中的文件监视程序从未看到此文件。没有过滤器集,因此默认设置为
*.*

如果我重命名该文件以删除点并用下划线替换它们,则文件观察者会看到该文件

我试着用谷歌搜索答案,但我的另一个问题是我不知道如何陈述这个问题——我们称之为多重延伸、多重点还是多重句点?所有这些都返回了无用的结果


所以我的问题是:是否可以设置一个文件监视程序来检测带有多个点扩展名的linux风格的文件名?如果你碰巧知道“多点文件扩展名”的正式术语,我很想知道它们叫什么。

我决定答案是,你不能,至少如果没有大量工作的话。我考虑过一个计时器,它每隔几秒钟就重命名一次多点文件,但这看起来很糟糕

我将文件查看器设置为在创建文件时启动,这是将控件拖动到设计图面时得到的结果

我更改了事件以检测更改,并根据大小进行过滤。看来。排除“多点”文件扩展名,为什么不呢?foo.bar.blah.zip不适合这个位置。图案我们需要的是类似ant的文件模式描述符(因为没有人提供更好的术语:-),但文档似乎不支持这些


让它监视文件大小的变化似乎会在创建文件时触发(从零变为某个值),这对我来说已经足够好了。一旦我知道文件在那里,不管控件的过滤器如何,我都可以得到它的名称。

我昨晚发布的答案没有通过回归测试。我得到了混合的结果和文件系统观察器的不同过滤器设置,它偶尔错过了文件,这是不可接受的。有很多关于网络共享问题的文章,但我认为这意味着观察者正在观察映射到不同计算机的网络共享,而不是被观察的目录本身就是运行服务的同一台计算机上的网络共享。延迟可能是我的一些mis触发的一个因素,但即使在本地,组件似乎也无法识别多点文件名

由于这是一项服务,我们已经有了一种方法来检测服务启动时已经存在的任何文件。该方法有效,不依赖于组件。因此,最优雅的解决方案是简单地将代码放在计时器上。下面是该类的相关部分(即,此代码段不是为复制/粘贴而设计的,只是为了说明我是如何解决问题的)。不要让FTP名字使你偏离正轨——它实际上只是监视一个共享文件夹,该文件夹可能映射到FTP服务器,也可能不映射到FTP服务器

using System.Collections.Generic;
using Timer = System.Timers.Timer;

public partial class VsiFtpManager : ServiceBase
{
    private Timer _searchTimer;
    private Queue<string> _filesToProcess;
    private string _ftpRoot; //this is set elsewhere from the registry

    protected override void OnStart(string[] args)
    {

        //process any files that are already there when the service starts
        LoadExistingFtpFiles(); 

        //Handle new files
        _searchTimer = new Timer(10000);
        _searchTimer.Elapsed += LoadExistingFtpFiles;
    }

    //convenience overload to allow this to handle timer events
    private void LoadExistingFtpFiles(object source, ElapsedEventArgs evtArgs)
    {
        LoadExistingFtpFiles();
    }

    private void LoadExistingFtpFiles()
    {
        _searchTimer.Stop();
        var di = new DirectoryInfo(_ftpRoot);
        FileInfo[] fileInfos = di.GetFiles("*.*", SearchOption.AllDirectories);
        foreach (FileInfo fi in fileInfos.Where(fi => fi != null))
        {
            if (fi.Extension != "processed" && !_filesToProcess.Contains(fi.FullName))
            {
                LogHelper.BroadcastLogMessage("INFO:  File " + fi.Name + " was uploaded.", EventLogEntryType.Information);
                _filesToProcess.Enqueue(fi.FullName);
                LogHelper.BroadcastLogMessage("File received: " + fi.Name, EventLogEntryType.Information);
            }
        }
        _searchTimer.Start();

    }
}
使用System.Collections.Generic;
使用定时器=System.Timers.Timer;
公共部分类VsiFtpManager:ServiceBase
{
私人定时器(searchTimer);;
专用队列_filesToProcess;
私有字符串_ftpRoot;//这是在注册表的其他位置设置的
启动时受保护的覆盖无效(字符串[]args)
{
//处理服务启动时已存在的任何文件
加载现有的ftpfiles();
//处理新文件
_searchTimer=新计时器(10000);
_searchTimer.appead+=LoadExistingFtpFiles;
}
//方便重载,允许它处理计时器事件
私有void加载现有ftpfiles(对象源,ElapsedEventArgs evtArgs)
{
加载现有的ftpfiles();
}
私有void LoadExistingFtpFiles()
{
_searchTimer.Stop();
var di=新目录信息(_ftpRoot);
FileInfo[]fileInfos=di.GetFiles(“**”,SearchOption.AllDirectories);
foreach(fileInfos.Where中的FileInfo-fi(fi=>fi!=null))
{
if(fi.Extension!=“processed”&&&!\u filesToProcess.Contains(fi.FullName))
{
LogHelper.BroadcastLogMessage(“信息:文件“+fi.Name+”已上载。”,EventLogEntryType.Information);
_filesToProcess.Enqueue(fi.FullName);
LogHelper.BroadcastLogMessage(“收到的文件:+fi.Name,EventLogEntryType.Information”);
}
}
_searchTimer.Start();
}
}
您没有看到的部分超出了我的问题的范围,本质上是一个针对队列_filesToProcess运行的协例程,该队列处理文件,然后将其重命名为扩展名.processed

所以我的最终答案是:我的研究,通过自动回归测试得到证实,表明文件系统观察者对于我的用例来说是不可靠的,它要求我处理复制到文件夹中的文件。其中一些文件将来自Unix系统,因此可能具有非windows文件名。net附带的文件系统监视程序组件无法可靠地检测名称中包含多个点的unix样式文件名


我用一个简单的轮询机制替换了文件系统监视程序。执行速度明显较慢但可靠,这是我的主要目标。整体解决方案减少了我的代码行,虽然不太重要,但删除了我在服务的设计表面上的唯一组件,这两个都是由于我自己可能的偏好而考虑的奖金。

你能显示相关代码吗?另外,请参见:“要监视所有文件中的更改,请将Filter属性设置为空字符串(“”),尽管后来声明为”“和“
*.
”。当您说“我有一个C#windows服务监视一个文件夹”时,是指这是别人编写的程序,还是您编写的程序?如果是您编写的,您可能希望发布一些代码。还有,你说的什么意思