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
,我认为这是因为在文件完全复制之前引发了事件。我该怎么克服?我只想将有效的图像文件添加到待办事项列表中,稍后我将逐一处理这些图像。
一个比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;
}