FileSystem Watcher-检查复制的文件是否为映像

本文关键字:是否 映像 文件 Watcher- 检查 复制 FileSystem | 更新日期: 2023-09-27 17:57:53

我正在使用FileSystem Watcher监视文件创建文件夹(Copied)事件。我只想让程序处理图像文件。

FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(watcher_FileCreated);
watcher.Path = path;

因此,我尝试创建一个位图,并在抛出异常时避免该文件

private static void watcher_FileCreated(object sender, FileSystemEventArgs e)
{
    try
    {
        using (Bitmap test = new Bitmap(Bitmap.FromFile(e.FullPath)))
        {
            mytoprocesslist.add(e.FullPath);
        }
        //do my processing with image 
        Console.WriteLine(e.FullPath);
    }
    catch (Exception error)
    {
       Console.WriteLine("File Error");
    }
 }

即使复制了有效的图像文件,也会抛出Out of Memory exception,我认为这是因为在文件完全复制之前引发了事件。我该怎么克服?我只想将有效的图像文件添加到待办事项列表中,稍后我将逐一处理这些图像。

FileSystem Watcher-检查复制的文件是否为映像

一个比Try-Catch更干净的解决方案可能是这个。我使用此代码时没有任何异常。

private static bool IsImage(string path) {
      try {
        var result = false;
        using (var stream = new FileStream(path, FileMode.Open)) {
          stream.Seek(0, SeekOrigin.Begin);
          var jpg = new List<string> { "FF", "D8" };
          var bmp = new List<string> { "42", "4D" };
          var gif = new List<string> { "47", "49", "46" };
          var png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" };
          var imgTypes = new List<List<string>> { jpg, bmp, gif, png };
          var bytesIterated = new List<string>();
          for (var i = 0; i < 8; i++) {
            var bit = stream.ReadByte().ToString("X2");
            bytesIterated.Add(bit);
            var isImage = imgTypes.Any(img => !img.Except(bytesIterated).Any());
            if (isImage) {
              result = true;
              break;
            }
          }
        }
        return result;
      } catch (UnauthorizedAccessException) {
        return false;
      }
    }

代码的使用

foreach (var file in Directory.EnumerateFiles(@"pathToFlowersFolder"))
            {
                Console.WriteLine($"File: {file} Result:{IsImage(file)}");
            }

编辑

玩过之后,我得到了IO异常(文件已在使用中)
阅读后,我会为您提供以下解决方案:

private void button1_Click(object sender, EventArgs e)
        {
            var watcher = new FileSystemWatcher();
            watcher.Created += new FileSystemEventHandler(fileSystemWatcher1_Changed);
            watcher.Path = @"c:'temp";
            watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
            watcher.EnableRaisingEvents = true;
        }
        private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)
        {
            Thread.Sleep(100); // <- give the Creator some time. Increase value for greate pause
            if (IsImage(e.FullPath))
            {
                Console.WriteLine("success----------->" + e.FullPath);
            }
        }

注意

这段代码在我的机器上正常工作。我的硬盘是固态硬盘,所以你可能需要增加线程睡眠时间。它适用于大小不超过7Mb的所有图像(jpg、bmp、gif、png)(我很确定,甚至更大)。

如果这个代码不适合你,请发布异常,而不是上传你的代码。

对于第一个要求:"我只想让程序处理图像文件"

private static void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
  string strFileExt = getFileExt(e.FullPath); 
  // filter file types 
  if (Regex.IsMatch(strFileExt, @"'.png|'.jpg", RegexOptions.IgnoreCase)) 
  { 
      //here Process the image file 
  }
} 

对于第二个要求:"内存不足异常"

这里发生的情况是,当创建文件(只有文件名和一些属性)时,系统正在调用创建的事件。然后文件更改事件也称为

因此,您必须在更改后的事件中进行处理。此外,为了防止重复调用,您必须为观察者添加一个筛选器。

以下是完整的代码

private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)
        {
            FileInfo fileInfo = new FileInfo(e.FullPath);
            string strFileExt = fileInfo.Extension;
            // filter file types 
            if (Regex.IsMatch(strFileExt, @"'.png|'.jpg", RegexOptions.IgnoreCase))
            {
                //here Process the image file 
                try
                {
                    using (Bitmap test = new Bitmap(Bitmap.FromFile(e.FullPath)))
                    {
                        //Do your code here.
                    }
                }
                catch (Exception error)
                {
                    Console.WriteLine("File Error");
                }
            }

        }
        private void Form1_Load(object sender, EventArgs e)
        {
            fileSystemWatcher1.Path = @"C:'Users'Christlin'Desktop'res";
            //To Prevent duplicated calling of changed event
            fileSystemWatcher1.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
        }