2016-07-21 4 views
1

FileSystem Watcher를 사용하여 File creation (Copied) 이벤트에 대한 폴더를 모니터링하고 있습니다. 이미지 파일 만 처리하도록 프로그램을 원합니다. 예외가FileSystem Watcher- 복사 한 파일이 이미지인지 확인

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을 던져 던져 경우

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

그래서 나는 파일을 비트 맵을 생성하고 피하려고 파일이 완전히 복사되기 전에 발생합니다. 이 문제를 어떻게 극복 할 수 있습니까? 나는 할 일 목록에 유효한 이미지 파일을 추가하기를 원하며 나중에이 이미지들을 하나씩 처리 할 것입니다.

+0

위 코드에는 메모리가 부족한 행이없는 것 같습니다. 대부분의 경우 "// 이미지 처리로 처리"가이 오류를 던지고 있습니다. 파일이 아직 완전히 복사되지 않았다면 1 초의 대기 시간을 추가 할 수 있습니다. – puneet

+0

@puneet'using (비트 맵 테스트 = 새 비트 맵 (Bitmap.FromFile (e.FullPath))) ' – techno

+0

'watcher.NotifyFilter = NotifyFilters.FileName;을 설정하고 이미지를로드하기 위해'Image.FromFile (e.FullPath); 그리고 그것은 예외없이 작동합니다. –

답변

1

Try-Catch보다 조금 깨끗한 해결책이 여기있을 수 있습니다. Im 예외없이이 코드를 사용합니다. 코드의

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)}"); 
      } 

편집

주위 재생 후 내가 제공하는 것 this를 읽고 후 IO-예외 (이미 사용중인 파일)
있어 당신은 다음 해결책 :

012 3,

참고

이 코드 조각은 제대로 내 컴퓨터에서 작동합니다. 내 HDD는 SSD이므로 스레드 수면 시간을 늘려야 할 수도 있습니다. 모든 이미지 (jpg, bmp, gif, png)에서 최대 7MB 크기까지 제대로 작동합니다.

이 코드가 효과가 없다면 코드를 업로드하는 대신 예외를 게시하십시오. "난 단지 원하는 이미지 파일을 처리 할 수있는 프로그램"두 번째 요구 사항에 대한

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 
    } 
} 

을 : : 첫 번째 요구 사항에 대한

+0

고마워요 ... 내가 다시 시도하고 ... btw 내가 downvote하지 않았다 :) – techno

+0

이것은 제대로 일부 jpg 이미지를 검색하지 못합니다. – techno

+0

예를 들어 주시겠습니까? jpg의 매직 넘버는 'FFd8'로 시작해야합니다. 진술 [여기] (http://stackoverflow.com/a/8755028/4558029) 여러 번 – lokusking

0

입니다 무슨 여기

"메모리 예외 부족", 때 파일을 시스템이 작성된 이벤트를 호출 중입니다 (파일 이름 및 일부 속성 만). 그런 다음 파일 변경 이벤트도 호출됩니다.

변경된 이벤트에서 처리해야합니다. 또한 중복 호출을 방지하려면 감시자에게 필터를 추가해야합니다.

다음은 전체 코드입니다.

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; 
     } 
+0

감사합니다 ... 변경된 일정에 연결했고 일정을 만들었습니다 ... 두 가지 일정에 모두 연결해야합니까? – techno

+0

OP 요구 사항에 따라 충분하지 않을 수 있습니다. 예를 들어 이미지에 다른 확장자 (예 : .txt)를 지정하여 쉽게 위장 할 수 있습니다. –

+0

@techno 변경된 및 Form1_Load 이벤트 만 충분합니다. –

관련 문제