c# - Moving files only if matching file exists -


i have application requires 2 files process data. zip file containing actual data control file says said data.

these files downloaded via sftp staging directory. once zip file complete, need check , see if control file there well. share naming prefix only(eg. 100001_abcdef_123456.zip paired 100001_abcdef_control_file.ctl.

i trying find way wait zip file finishing downloading move files on fly, while maintaining directory structure important next step in processing.

currently waiting till sftp worker finishes calling robocopy move everything. more polished approach.

i have tried several things , same results. files download never move. reason cannot compare work correctly.

i have tried using filesystemwatcher rename filepart zip seems miss several downloads , reason function dies when foreach search directory control file. below filesystemwatcher event, calling created , changed. below setup filesystemwatcher.

        watcher.path = @"c:\sync\";         watcher.includesubdirectories = true;         watcher.enableraisingevents = true;         watcher.filter = "*.zip";         watcher.notifyfilter = notifyfilters.attributes |                                notifyfilters.creationtime |                                notifyfilters.filename |                                notifyfilters.lastaccess |                                notifyfilters.lastwrite |                                notifyfilters.size |                                notifyfilters.security |                                 notifyfilters.creationtime |                                 notifyfilters.directoryname;         watcher.created += watcher_changed;         watcher.changed += watcher_changed;   private void watcher_changed(object sender, filesystemeventargs e)     {         var dir = new directoryinfo(e.fullpath.substring(0, e.fullpath.length - e.name.length));         var files = dir.getfiles();          fileinfo zipfile = new fileinfo(e.fullpath);          foreach (fileinfo file in files)         {             messagebox.show(file.extension);             if (file.extension == "ctl" && file.name.startswith(e.name.substring(0, (e.name.length - 14))))             {                 file.copyto(@"c:\inp\");                 zipfile.copyto(@"c:\inp\");             }         }     } 

the filesystemwatcher class notoriously tricky use correctly, because multiple events single file being written to, moved or copied, @willstoltenberg mentioned in answer.

i have found easier setup task runs periodically (e.g. every 30 seconds). problem, below. note similar implementation using timer, instead of task.delay, may preferable.

public class myperiodicwatcher  {     private readonly string _watchpath;     private readonly string _searchmask;     private readonly func<string, string> _commonprefixfetcher;     private readonly action<fileinfo, fileinfo> _pairprocessor;     private readonly timespan _checkinterval;     private readonly cancellationtoken _canceltoken;      public myperiodicwatcher(         string watchpath,         string searchmask,         func<string, string> commonprefixfetcher,         action<fileinfo, fileinfo> pairprocessor,         timespan checkinterval,         cancellationtoken canceltoken)     {         _watchpath = watchpath;         _searchmask = string.isnullorwhitespace(searchmask) ? "*.zip" : searchmask;         _pairprocessor = pairprocessor;         _commonprefixfetcher = commonprefixfetcher;         _canceltoken = canceltoken;         _checkinterval = checkinterval;     }      public task watch()     {         while (!_canceltoken.iscancellationrequested)         {             try             {                 foreach (var file in directory.enumeratefiles(_watchpath, _searchmask))                 {                     var pairprefix = _commonprefixfetcher(file);                     if (!string.isnullorwhitespace(pairprefix))                     {                         var match = directory.enumeratefiles(_watchpath, pairprefix + "*.ctl").firstordefault();                         if (!string.isnullorempty(match) && !_canceltoken.iscancellationrequested)                             _pairprocessor(                                 new fileinfo(path.combine(_watchpath, file)),                                 new fileinfo(path.combine(_watchpath, match)));                     }                     if (_canceltoken.iscancellationrequested)                         break;                 }                 if (_canceltoken.iscancellationrequested)                     break;                  task.delay(_checkinterval, _canceltoken).wait().configureawait(false);             }             catch (operationcanceledexception)             {                 break;             }         }     } } 

you need provide

  • the path monitor
  • the search mask first file (i.e. *.zip)
  • a function delegate gets common file name prefix zip file name
  • an interval
  • the delegate perform moving , receives fileinfo pair processed / moved.
  • and cancellation token cleanly cancel monitoring.

in pairprocessor delegate, catch io exceptions, , check sharing violation (which means writing file has not yet completed).


Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -