FileSystemWatcher C#-无法访问文件,因为它正在被另一个进程使用

问题描述 投票:1回答:1

我正在使用FileSystemWatcher检测目录更改,然后读取文件内容并将其插入数据库。

这是我的代码:

private FileSystemWatcher _watcher;

public MainWindow()
{
    try
    {
        InitializeComponent();

        GetFiles();

        //Task.Factory.StartNew(() => GetFiles())
        //   .ContinueWith(task =>
        //   {
        //   }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }
    catch(Exception ex)
    {
        //..
    }
}

public bool GetFiles()
{
    _watcher = new FileSystemWatcher(Globals.iniFilesPath, "*.ini");
    _watcher.Created += FileCreated;
    _watcher.IncludeSubdirectories = false;
    _watcher.EnableRaisingEvents = true;
    return true;
}

private void FileCreated(object sender, FileSystemEventArgs e)
{
    try
    {
        string fileName = Path.GetFileNameWithoutExtension(e.FullPath);

        if (!String.IsNullOrEmpty(fileName))
        {
            string[] content = File.ReadAllLines(e.FullPath);
            string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();

            ChargingStationFile csf = new Product
            {
                Quantity = Convert.ToDecimal(newStringArray[1]),
                Amount = Convert.ToDecimal(newStringArray[2]),
                Price = Convert.ToDecimal(newStringArray[3]),
                FileName = fileName
            };

            ProductController.Instance.Save(csf);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

如果我使用CTRL + F5运行此代码,则收到此消息:

enter image description here

但是如果我使用F5

](调试模式),则会收到此错误,并且不会收到有关无法访问进程的错误,并且成功保存了项目。这真让我感到困惑。

我应该安排观察者吗?或类似的东西?也许我在这里想念什么?enter image description here

这是我第一次使用FileSystemWatcher,显然这里确实有问题。.

P.S,我发现此行引起异常:

string[] content = File.ReadAllLines(e.FullPath);

怎么来?

谢谢你们

欢呼声

我正在使用FileSystemWatcher来检测目录更改,然后读取文件内容并将其插入数据库。这是我的代码:private FileSystemWatcher _watcher;公共MainWindow(){...

this答案中所述:

最有可能在这里发生的是FileCreated事件是被提出并尝试在之前处理文件完全写入磁盘。

因此,您需要等待文件复制完成。根据this other answer

从FileSystemWatcher的文档中:

一旦创建文件,就会引发OnCreated事件。如果一个文件被复制或转移到监视的目录中,即OnCreated事件将立即引发,然后是一个或多个OnChanged事件。

因此,针对您的情况的解决方法是创建一个字符串列表,其中包含在Created方法处理程序中无法读取的文件的路径,并在FileSystemWatcher的Changed事件中重新处理这些路径(请阅读代码中的注释):

public partial class MainWindow : Window {
    private FileSystemWatcher _watcher;

    public MainWindow() {
        try {
            InitializeComponent();

            GetFiles();
        } catch (Exception ex) {
            MessageBox.Show($"Exception: {ex.Message}");
        }
    }

    private bool GetFiles() {
        _watcher = new FileSystemWatcher(@"C:\TestFolder", "*.ini");
        _watcher.Created += FileCreated;
        _watcher.Changed += FileChanged; // add this.
        _watcher.IncludeSubdirectories = false;
        _watcher.EnableRaisingEvents = true;
        return true;
    }

    // this field is new, and contains the paths of the files that could not be read in the Created method handler. 
    private readonly IList<string> _waitingForClose = new List<string>();

    private void FileChanged(object sender, FileSystemEventArgs e) {
        if (_waitingForClose.Contains(e.FullPath)) {
            try {
                string[] content = File.ReadAllLines(e.FullPath);
                string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();

                MessageBox.Show($"On FileChanged: {string.Join(" --- ", newStringArray)}");

                // Again, process the data from the file to saving in the database.

                // removing the path, so as not to reprocess the file..
                _waitingForClose.Remove(e.FullPath);
            } catch (Exception ex) {
                MessageBox.Show($"Exception on FileChanged: {ex.Message} - {e.FullPath}");
            }
        }
    }

    private void FileCreated(object sender, FileSystemEventArgs e) {
        try {
            string fileName = Path.GetFileNameWithoutExtension(e.FullPath);

            if (!String.IsNullOrEmpty(fileName)) {
                string[] content = File.ReadAllLines(e.FullPath);
                string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();

                MessageBox.Show($"On FileCreated: {string.Join(" --- ", newStringArray)}");

                // process the data from the file to saving in the database.
            }
        } catch (Exception ex) {
            // if the method fails, add the path to the _waitingForClose variable
            _waitingForClose.Add(e.FullPath);
            //MessageBox.Show($"Exception on FIleCreated: {ex.Message} - {e.FullPath}");
        }
    }
}
c# wpf filesystemwatcher system.io.file
1个回答
0
投票

this答案中所述:

© www.soinside.com 2019 - 2024. All rights reserved.