2017-05-22 280 views
0

Filewatcher를 사용하여 폴더에서 파일을 감지하고 파일을 새 위치로 이동하려고했습니다. 콘솔 응용 프로그램을 사용하는 동안 The process cannot access the file because it is being used by another process으로 오류가 발생합니다.다른 프로세스에서 사용 중이기 때문에 프로세스가 파일에 액세스 할 수 없습니다. Filewatcher - C# - 콘솔 응용 프로그램

File.Move(f.FullName, System.IO.Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", Path.GetFileName(f.FullName)));에서 OnChanged 방법으로이 오류가 발생합니다. 아래 코드를 확인하고이 문제를 해결해주십시오. 미리 감사드립니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Security.Permissions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      Run(); 

     } 

     [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 

     public static void Run() 
     { 


      FileSystemWatcher watcher = new FileSystemWatcher(); 
      watcher.Path = @"C:\Users\ADMIN\Downloads\FW_Source"; 
      watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
      | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
      watcher.Filter = "*.*"; 

      watcher.Created += new FileSystemEventHandler(OnChanged); 
      watcher.EnableRaisingEvents = true; 

      Console.WriteLine("Press \'q\' to quit the sample."); 
      while (Console.Read() != 'q') ; 
     } 


     private static void OnChanged(object source, FileSystemEventArgs e) 
     { 

      DirectoryInfo directory = new DirectoryInfo(@"C:\Users\ADMIN\Downloads\FW_Source\"); 
      FileInfo[] files = directory.GetFiles("*.*"); 
      foreach (var f in files) 
      { 
       File.Move(f.FullName, System.IO.Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", Path.GetFileName(f.FullName))); 
      } 

     } 


    } 
} 

답변

5

파일이 변경되는 동안 Changed 이벤트가 발생합니다. 파일에 대한 프로세스 쓰기가 완료되기 전에 이동하려고합니다. I

먼저 파일을 닫고 파일을 닫은 후에 만 ​​파일을 단독으로 열려고 시도합니다 (읽기 거부, 쓰기 거부). 성공하지 못하면 몇 초 후에 다시 시도하십시오.

+0

'디렉토리 찾을 수 없습니다 예외였다 처리 오류. 도와 주시겠습니까? – METALHEAD

+0

폴더의 모든 파일을 이동하고 있지만 여러 개의 알림이있을 수 있습니다. 변경된 파일을 이동해야합니다. – BugFinder

+0

안녕하세요. 원본 폴더에 하나의 파일 만 넣었습니다. 여전히'Directory Not found Exception was treated' 오류가 발생합니다. 도와 주실 수 있니? – METALHEAD

1

대신 감시 폴더의 모든 파일을 이동하는, 너무처럼, 생성 된 파일을 이동 :

private static void OnChanged(object source, FileSystemEventArgs e) 
{ 
    File.Move(e.FullPath, Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", e.Name)); 
} 

것 2 초 대기 Thread.Sleep(2000) 것보다 더 좋은 방법은 다음과 같이

private static async void OnChanged(object source, FileSystemEventArgs e) 
{ 
    await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false); 

    File.Move(e.FullPath, Path.Combine(targetFolder, e.Name)); 
} 

이렇게하면 많은 파일이 동시에 복사되는 경우 프로그램에서 여러 스레드를 잠그지 않게됩니다.

+0

안녕하세요, 귀하의 의견을 보내 주셔서 감사합니다. 여전히 동일한 예외가 발생합니다. '프로세스가 다른 프로세스에서 사용 중이므로 파일에 액세스 할 수 없습니다. '. 당신이 나를 도울 수 있나요?, – METALHEAD

+0

안녕하세요,'File.Move (e.FullPath, Path.Combine (@ "C : \ Users \ ADMIN \ Downloads \ FW_Dest", e.Name)) 전에 Thread.Sleep (2000) ; '일했다. ur 답변을 주셔서 대단히 감사합니다. – METALHEAD

+0

답변 해 주셔서 감사합니다. – METALHEAD

0

큰 파일을 감시 폴더로 이동하면이 문제가 발생합니다.

OnChange 메서드에서 IsLocked 메서드를 호출했으며 false를 반환 할 때까지 이동하지 않습니다.

while (IsFileLocked(ImportFormat.FileName)) { 
    //Do nothing until the file is finished writing 
} 

IsLocked 방법 : 나는 내가, 내가 무엇입니까 파일 이동 작업 전에 (2000) Thread.sleep를 배치 한 몇 초 - 기다렸다

/// <summary> 
///  Tries to open the file for R/W to see if its lock. Returns Boolean 
/// </summary> 
/// <param name="filePath"></param> 
/// <returns>bool</returns> 
protected static bool IsFileLocked(string filePath) { 
    FileStream stream = null; 
    var file = new FileInfo(filePath); 
    try { 
     stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    }catch (IOException err) { 
     //the file is unavailable because it is: 
     //still being written to 
     //or being processed by another thread 
     //or does not exist (has already been processed) 
     return true; 
    } finally { 
     stream?.Close(); 
    } 

    //file is not locked 
    return false; 
}