2008-11-10 3 views
3

특정 종류의 파일 (*. mbxml)에 대해 .net 파일 워처를 사용하여 폴더를 모니터링하고 있습니다. 나는 그것을 위해 filewatcher의 생성 된 이벤트를 사용하고 있습니다. 생성 된 이벤트가 발생하면이 파일을 다른 폴더로 이동해야합니다. 이 방법의 문제점은 파일 복사가 시작되자 마자 생성 된 이벤트가 시작된다는 것입니다. 따라서 파일이 감시되는 폴더로 복사하는 데 너무 오래 걸리면 파일을 이동시키는 코드가 실패합니다. 검색 한 적이 있고 그물에서 찾은 유일한 해결책은 try-catch 블록 내에서 파일을 이동하고 전체 파일이 복사 될 때까지 계속 시도하는 것입니다. 나는이 솔루션을 좋아하지 않는다. 전체 파일이 복사를 마쳤거나 생성 된 이벤트가 복사되면 이벤트가 발생했다면 더 좋았을 것이다. 이것을 달성하는 다른 방법이 있습니까?Filewatcher created event

답변

2

나는 try catch 블록을 제외하고는 어쨌든이 작업을 수행하지 못했습니다. 대개 oncreate 이벤트에서 파일을 열려고 시도하는 bool을 설정합니다. 이 방법은 코드의 나머지 부분이 계속 진행될 것인지 결정합니다.

private static bool creationComplete(string fileName) 
    { 
     // if the file can be opened it is no longer locked and now available 
     try 
     { 
      using (FileStream inputStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None)) 
      { 
       return true; 
      } 
     } 
     catch (IOException) 
     { 
      return false; 
     } 
    } 
2

파일을 만드는 프로그램을 변경할 수 있습니까? 그렇다면 하나의 폴더에서 생성 한 다음 다른 폴더로 (원자 적으로) 이동하거나 다른 확장 (실제로 추적 할 수있는 것)을 사용하십시오.

1

BinaryReader 및 BinaryWriter를 사용하여 파일을 옮겨 보았습니까? 복사되는 동안 파일을 읽을 수 있고 느린 속도로 쓸 수 있으므로 다른 프로세스가 파일을 만드는 속도보다 이동 속도가 빠르지 않게됩니다. 또한 읽기 사이에 대기 시간을 삽입 할 수도 있습니다. 마지막으로 읽은 다음 파일 작성이 완료되었는지 확인한 다음 삭제할 수 있습니다.

행운을 빈다.

1

다른 프로그램이 파일에 쓰는 것을 끝내는지를 확인하는 유일한 방법은 SUCCEED 파일 open() 호출에 대한 것입니다. FAILURE는 여전히 기록되는 파일의 정의입니다.

일반적으로 while() 루프는 thread.sleep 타이머와 함께 사용되며 A 타임 아웃 또는 B) 성공할 때까지 계속 시도합니다.

0

올바르게 호출하면 FileWatcher는 주어진 파일/폴더에서 IO 당 여러 이벤트를 발생시킵니다. 완료와 관련된 FileSystemEventArgs의 범위를 좁힐 수 있습니다. 파일에 액세스 할 수 있는지 확인하는 것을 연기해야 ​​할 수도 있지만 필자는 그 파일이 덜 바람직한 해결책이라고 생각할 것입니다.

2

에서 : http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

"일반적인 파일 시스템 작업은 하나 개 이상의 이벤트를 발생시킬 수있는 예를 들어, 파일이 한 디렉토리에서 다른 디렉토리로 이동 여러는 onChanged 및 일부 OnCreated 및 이벤트가 발생 될 수 OnDeleted 때.. 파일 이동은 여러 개의 간단한 작업으로 구성되는 복잡한 작업이므로 여러 이벤트가 발생하며 FileSystemWatcher가 감지하는 추가 파일 시스템 이벤트가 발생할 수 있습니다. "

시간에 민감한 시간 파일 이동에 대한 귀하의 요구 사항은 무엇입니까?

당신이 이동하려고 시도하는 예외를 잡기, 당신의 성공은 당신이 약간 다른 접근 방식을 취할 수 얻을 때까지 반복의 아이디어를 좋아하지 않는 경우에.

Created 이벤트를 받으면 파일의 마지막 쓰기 시간을 모니터링하기 시작합니다. 마지막 쓰기 시간 (예 : 2 초)이 지난 후 특정 시간이 지나면 파일을 옮길 수 있습니다. 아마도 '실패한'동작이 훨씬 적지 만 최종 결과는 동일합니다.

2

생성 된 이벤트를 감시하지만 마지막 쓰기 시간 변경 이벤트를 기다립니다. 파일 복사가 완료되면 마지막 쓰기 시간이 업데이트됩니다. 파일을 이동하기 때문에 마지막 쓰기 시간 변경 이벤트 만 처리 할 수 ​​있습니다.

그냥은 FileSystemWatcher에서 상속 등처럼, 자신의 FileReady 이벤트를 fireing하여 코드를 간단하게 만들 수
3

:

public class CustomFileSystemWatcher : System.IO.FileSystemWatcher 
{ 
    public CustomFileSystemWatcher() 
    { 
     this.Created += new FileSystemEventHandler(CustomFileSystemWatcher_Created); 
    } 


    private void CustomFileSystemWatcher_Created(object sender, FileSystemEventArgs e) 
    { 
     ThreadPool.QueueUserWorkItem((n) => { WaitFileReady(e); }); 
    } 

    private void WaitFileReady(FileSystemEventArgs e) 
    { 
     while (true) 
     { 
      try 
      { 
       using (FileStream fs = File.Open(e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
       { 
        //exit 
        break; 
       } 
      } 
      catch (Exception) 
      { 
       //wait if you like 
       Thread.Sleep(100); 
      } 
     } 
     OnFileReady(e); 
    } 

    public event FileSystemEventHandler FileReady; 

    protected virtual void OnFileReady(FileSystemEventArgs e) 
    { 
     if (this.EnableRaisingEvents && FileReady != null) FileReady(this, e); 
    } 
} 
+0

귀하의 코드는 기본적으로 같은 방법을 사용하면 당신의 상속 클래스의 코드를 작성했습니다있다 . – Raminder