我正在使用FileSystem Watcher监视文件夹创建文件(复制)事件。我只希望程序处理图像文件。
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(watcher_FileCreated);
watcher.Path = path;
所以我尝试创建一个Bitmap,并在抛出异常时避开该文件
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
,我认为这是因为在完全复制文件之前引发了事件。我怎么能克服这个?我只想将有效的图像文件添加到待办事项列表中,我将逐个处理这些图像。
答案 0 :(得分:1)
比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-Exception(文件已经在使用中)
阅读this后,我将为您提供以下解决方案:
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);
}
}
注意强>
这段代码适用于我的机器。我的硬盘是SSD,因此您可能需要增加线程休眠时间。它适用于所有图像(jpg,bmp,gif,png),最大尺寸为7 Mb(我非常肯定和更高)。
如果此代码不适合您,请发布例外而非上传您的代码。
答案 1 :(得分:0)
对于第一个要求:“我只希望程序处理图像文件”
on
对于第二个要求:“Out of Memory Exception”
这里发生的是,当创建文件时(仅文件名和一些属性),系统正在调用创建的事件。然后文件更改事件也称为
所以你必须在改变的事件中进行处理。另外,为防止重复呼叫,您必须向观察者添加过滤器。
以下是完整的代码。
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
}
}