파일을 수정할 때 이벤트를 트리거하는 filesystemwatcher가 있습니다. 자물쇠가 제거되면 그 파일을 읽고 싶습니다. 큰 파일을 복사 할 때 이벤트가 전송 된 후 잠시 동안 파일 잠금이 유지되면서 파일이 읽기 액세스를 위해 열리지 않도록하면서 이벤트가 트리거되면이 파일을 열려고합니다.파일 스트림 열기를위한 FileSystemWatcher 트리거
제안 사항?
파일을 수정할 때 이벤트를 트리거하는 filesystemwatcher가 있습니다. 자물쇠가 제거되면 그 파일을 읽고 싶습니다. 큰 파일을 복사 할 때 이벤트가 전송 된 후 잠시 동안 파일 잠금이 유지되면서 파일이 읽기 액세스를 위해 열리지 않도록하면서 이벤트가 트리거되면이 파일을 열려고합니다.파일 스트림 열기를위한 FileSystemWatcher 트리거
제안 사항?
내가 마지막으로 문제를 처리 한 이후로 문제 공간이 크게 변경되지 않는 한이 프로그램은 실제로 약간의 doozie입니다.
가장 쉬운 방법은 파일을 열어 결과로 나타나는 IOException
을 잡는 것입니다. 파일이 잠겨 있으면 나중에 확인할 대기열에 파일을 추가하십시오. 동일한 파일에 대해 여러 개의 이벤트가 생성되는 모든 종류의 경우가 있기 때문에 들어오는 모든 파일을 처리 할 수는 없으므로 수신 된 모든 이벤트에 대해 재시도 루프를 설정하면 재앙이 될 수 있습니다. 대신 대기열에 넣고 일정한 간격으로 대기열을 확인해야합니다. 여기
public class FileMonitor : IDisposable
{
private const int PollInterval = 5000;
private FileSystemWatcher watcher;
private HashSet<string> filesToProcess = new HashSet<string>();
private Timer fileTimer; // System.Threading.Timer
public FileMonitor(string path)
{
if (path == null)
throw new ArgumentNullException("path");
watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += new FileSystemEventHandler(FileCreated);
watcher.EnableRaisingEvents = true;
fileTimer = new Timer(new TimerCallback(ProcessFilesTimer),
null, PollInterval, Timeout.Infinite);
}
public void Dispose()
{
fileTimer.Dispose();
watcher.Dispose();
}
private void FileCreated(object source, FileSystemEventArgs e)
{
lock (filesToProcess)
{
filesToProcess.Add(e.FullPath);
}
}
private void ProcessFile(FileStream fs)
{
// Your code here...
}
private void ProcessFilesTimer(object state)
{
string[] currentFiles;
lock (filesToProcess)
{
currentFiles = filesToProcess.ToArray();
}
foreach (string fileName in currentFiles)
{
TryProcessFile(fileName);
}
fileTimer.Change(PollInterval, Timeout.Infinite);
}
private void TryProcessFile(string fileName)
{
FileStream fs = null;
try
{
FileInfo fi = new FileInfo(fileName);
fs = fi.OpenRead();
}
catch (IOException)
{
// Possibly log this error
return;
}
using (fs)
{
ProcessFile(fs);
}
lock (filesToProcess)
{
filesToProcess.Remove(fileName);
}
}
}
(주 - 버그가 있다면 알려주세요 - 완벽하지 않을 수도 있습니다, 그래서 내가 여기에 메모리에서이 리콜 해요 .)
니스, 내가 기다리고있는 동안 같이 갔다. 나는 타임 아웃과 재시도 대기를 사용했다. 나는 좀 더 우아하고 좋은 것을 원했었다.) (대단한 답변을 얻으려는 노력에 대한 백만의 감사) – Matthew