C# Directory.GetFiles失败,错误为进程无法访问该文件,因为另一个进程正在使用该文件

C# Directory.GetFiles失败,错误为进程无法访问该文件,因为另一个进程正在使用该文件,c#,.net,C#,.net,我的代码是 var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly); 其中File.FileMatchPattern类似于“FileName*.csv”,而DirectoryPath是unc共享 在dev中,此代码执行良好,但在uat中,我们得到以下异常: ERROR 8 Guggenheim.Pipeline.Services.F

我的代码是

var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly);
其中File.FileMatchPattern类似于“FileName*.csv”,而DirectoryPath是unc共享

在dev中,此代码执行良好,但在uat中,我们得到以下异常:

ERROR 8 Guggenheim.Pipeline.Services.FileWatcher.WatchedFile - CheckForFile
System.IO.IOException: The process cannot access the file '\\il1tstbrsapp01\prodapps\FileWatcher\EPAMFileWatcherDropFolderTest\20140531_0171' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileSystemEnumerableIterator`1.CommonInit()
   at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
   at System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
   at Guggenheim.Pipeline.Services.FileWatcher.WatchedFile.CheckForFile() in e:\VS\FixedIncome\Pipeline.Services\Guggenheim.Pipeline.Services.FileWatcher\Guggenheim.Pipeline.Services.FileWatcher\WatchedFile.cs:line 71
奇怪的是错误的路径是一个目录而不是一个文件,应该注意的是,该目录正被一个FileSystemWatcher监视

我真的不在乎文件是否被另一个进程访问,我只想知道此时它是否在那里。有没有办法在.NET/C#中搜索目录中的文件而不必考虑锁

编辑: 我正在用以下代码查看文件夹:

Watcher = new FileSystemWatcher(group.WatchDirectory);
            Watcher.IncludeSubdirectories = true;
            Watcher.NotifyFilter = NotifyFilters.DirectoryName;
            Watcher.Created += Watcher_Created;
            WatchedGroups = new List<WatchedGroup>();
            Watcher.EnableRaisingEvents = true;
WatchedGroup如下所示:

public class WatchedGroup : IDisposable
{
    public FileWatcherGroup Group { get; private set; }
    private Timer GroupTimer { get; set; }
    public List<WatchedFile> Files { get; private set; }
    public string DirectoryPath { get; private set; }
    public event EventHandler GroupReady;
    public event EventHandler GroupFailed;
    public bool IsGroupReady { get; private set; }
    private readonly object sync = new object();
    public WatchedGroup(FileWatcherGroup group, string directory)
    {
        this.Group = group;
        this.GroupTimer = new Timer(Group.WaitTimeInMinutes * 60000);
        this.GroupTimer.Elapsed += GroupTimer_Elapsed;
        this.DirectoryPath = directory;
        Files = Group.Files.Select(f => new WatchedFile(f, directory)).ToList();
        CheckGroupReady();
        if (IsGroupReady)
            return;
        foreach(var file in Files)
        {
            file.FileAvailable += File_FileAvailable;
        }
        this.GroupTimer.Start();
    }
    private void StopFiles()
    {
        foreach(var file in Files)
        {
            file.Stop();
        }
        this.GroupTimer.Stop();
    }
    private void CheckFiles()
    {
        foreach(var file in Files.Where(f => !f.IsFileAvailable))
        {
            file.CheckForFile();
        }
    }
    private void CheckGroupReady()
    {
        lock (sync)
        {
            if (!IsGroupReady && Files.All(f => f.IsFileAvailable))
            {
                IsGroupReady = true;
                StopFiles();
                if (GroupReady != null)
                    GroupReady(this, new EventArgs());

            }
        }
    }
    private void File_FileAvailable(object sender, EventArgs e)
    {
        CheckGroupReady();
    }

    private void GroupTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        GroupTimer.Stop();
        StopFiles();
        CheckFiles();
        CheckGroupReady();
        if (!IsGroupReady && GroupFailed != null)
            GroupFailed(this, new EventArgs());
    }

    public void Dispose()
    {
        this.StopFiles();
        this.Files.Clear();
    }
}
public class WatchedFile
{
    private static readonly ILog logger = LogManager.GetLogger(typeof(WatchedFile));
    public WatcherFile File { get; private set; }
    public bool IsFileAvailable { get; private set; }
    public event EventHandler FileAvailable;
    private FileSystemWatcher Watcher { get; set; }
    public string DirectoryPath { get; private set; }
    public string FilePath { get; private set; }
    public WatchedFile(WatcherFile file, string directoryPath)
    {
        this.File = file;
        this.DirectoryPath = directoryPath;
        CheckForFile();
        if (IsFileAvailable)
            return;
        try
        {
            Watcher = new FileSystemWatcher(directoryPath);
            Watcher.Filter = File.FileMatchPattern;
            Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
            Watcher.Created += Watcher_Created;
            Watcher.EnableRaisingEvents = true;
        }
        catch(Exception ex)
        {
            logger.Error("WatchedFile FileSystemWatcher", ex);
            throw;
        }

    }
    public void Stop()
    {
        if(Watcher != null)
            Watcher.EnableRaisingEvents = false;
    }
    private void Watcher_Created(object sender, FileSystemEventArgs e)
    {
        this.FilePath = e.FullPath;
        MarkFileAvailable();
    }
    private readonly object sync = new object();
    private void MarkFileAvailable()
    {
        lock(sync)
        {
            if(!this.IsFileAvailable)
            {
                this.IsFileAvailable = true;
                if (FileAvailable != null)
                    FileAvailable(this, new EventArgs());
            }
        }
    }
    public bool CheckForFile()
    {
        try
        {
            var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly);
            if (files.Length > 0)
            {
                this.FilePath = files.First();
                MarkFileAvailable();
            }
            return this.IsFileAvailable;
        }
        catch(Exception ex)
        {
            logger.Error("CheckForFile", ex);
            throw;
        }
    }
}

此代码的目的是允许最终用户在网络共享上放置一个文件夹,该文件夹应包含一组由模式(例如文件名*.csv)定义的文件,如果所有文件都在设定的时间内出现,则会触发下游系统拾取的事件,如果没有,则会触发一个失败事件。

如果您在当前正在写入的文件夹中使用Directory.GetFiles,则会出现这种情况,因为您说可以随时删除文件

有关讨论的各种想法,请参见和

您可能需要考虑离开<代码>目录> GETFrase<代码>。将其包装在异常处理程序中并重试会很难看,而且无法执行


第二个链接包含另一种方法,即文件写入中间文件夹,并且仅在写入完成后才移动到目标文件夹(在同一驱动器上)

你能把你的完整密码贴出来吗。问题可能在于您试图对文件执行的操作。如果您正在使用FileSystemWatcher事件启动它,它可能仍在创建文件。事件会立即触发,它不会等到文件完全创建完毕。我将修改entryHmya、文件系统giveth和taketh。当他们在一台你看不见的机器上,可能运行一些非Windows操作系统时,他们会得到更多。您需要与管理该文件共享的人交谈。如果他不记得对服务器做过任何可能触发此错误的特定操作,那么他可以在serverfault.com上询问相关问题
public class WatchedFile
{
    private static readonly ILog logger = LogManager.GetLogger(typeof(WatchedFile));
    public WatcherFile File { get; private set; }
    public bool IsFileAvailable { get; private set; }
    public event EventHandler FileAvailable;
    private FileSystemWatcher Watcher { get; set; }
    public string DirectoryPath { get; private set; }
    public string FilePath { get; private set; }
    public WatchedFile(WatcherFile file, string directoryPath)
    {
        this.File = file;
        this.DirectoryPath = directoryPath;
        CheckForFile();
        if (IsFileAvailable)
            return;
        try
        {
            Watcher = new FileSystemWatcher(directoryPath);
            Watcher.Filter = File.FileMatchPattern;
            Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
            Watcher.Created += Watcher_Created;
            Watcher.EnableRaisingEvents = true;
        }
        catch(Exception ex)
        {
            logger.Error("WatchedFile FileSystemWatcher", ex);
            throw;
        }

    }
    public void Stop()
    {
        if(Watcher != null)
            Watcher.EnableRaisingEvents = false;
    }
    private void Watcher_Created(object sender, FileSystemEventArgs e)
    {
        this.FilePath = e.FullPath;
        MarkFileAvailable();
    }
    private readonly object sync = new object();
    private void MarkFileAvailable()
    {
        lock(sync)
        {
            if(!this.IsFileAvailable)
            {
                this.IsFileAvailable = true;
                if (FileAvailable != null)
                    FileAvailable(this, new EventArgs());
            }
        }
    }
    public bool CheckForFile()
    {
        try
        {
            var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly);
            if (files.Length > 0)
            {
                this.FilePath = files.First();
                MarkFileAvailable();
            }
            return this.IsFileAvailable;
        }
        catch(Exception ex)
        {
            logger.Error("CheckForFile", ex);
            throw;
        }
    }
}