private Task ScanExistingFilesToProcess(CancellationToken ct) { lock (_scanLock) { if (_fileScanTask.IsCanceled || _fileScanTask.IsCompleted || _fileScanTask.IsFaulted) { _fileScanTask = Task.Run( () => { foreach (string filePath in SafeFileEnumerator.EnumerateFiles(this.Settings.SourceFolder, this.Settings.Filter, SearchOption.AllDirectories)) { if (ct.IsCancellationRequested) { break; } FileInfo sourceInfo; try { sourceInfo = new FileInfo(filePath); } catch (IOException) { continue; } foreach (var folder in this.Settings.DestinationFolders) { // do not stop the processing here in case of cancellation // because we must stay coherent when sending events by file // i.e. we must be careful not to send a partial destination list for a file var destInfo = new FileInfo(GetDestinationFilePath(filePath, folder)); if (!IOHelper.AreSameFile(sourceInfo, destInfo)) { var newFileData = new FileTransferData { MachineName = Environment.MachineName, MonitoredFolderPath = _monitor.Path, DestinationFolderPath = folder, FileName = sourceInfo.Name, TotalBytes = sourceInfo.Length }; _fileTransferSubject.OnNext(newFileData); } } } }); } } return(_fileScanTask); }
internal void Initialize() { ValidateConfig(); _monitor = new FileMonitor(this.Settings.SourceFolder, filter: this.Settings.Filter, watchedChangeTypes: WatcherChangeTypes.Created | WatcherChangeTypes.Changed); _monitor.IncludeSubdirectories = true; _monitorObserver = _monitor.FileChangedDataSource .ObserveOn(TaskPoolScheduler.Default) .Subscribe( fileEvent => { if (fileEvent.ChangeType == WatcherChangeTypes.Created) { foreach (var folder in this.Settings.DestinationFolders) { var newFile = new FileTransferData { MachineName = Environment.MachineName, MonitoredFolderPath = _monitor.Path, DestinationFolderPath = folder, FileName = fileEvent.Name, TotalBytes = new FileInfo(fileEvent.FullPath).Length }; _fileTransferSubject.OnNext(newFile); } } _newFileEvent.Set(); }, exception => { Log.Warn().Exception(exception).Write(); var errorData = new FileTransferData { MachineName = Environment.MachineName, MonitoredFolderPath = _monitor.Path, Exception = exception }; _fileTransferSubject.OnNext(errorData); }); }
private void StartDownloadLastRdFile() { if (string.IsNullOrEmpty(this.SequenceId)) { throw new InvalidOperationException("SequenceId is missing. RD file not downloaded."); } if (string.IsNullOrEmpty(this.SaveFolderAbsolutePath)) { throw new InvalidOperationException("SaveFolderPath is missing. RD file not downloaded."); } this.IsTransferring = true; this.CurrentFileTransfer = Task.Run( async() => { try { using (var client = new UdpClient(new IPEndPoint(this.RemoteAddress, this.UdpSenderPort))) { byte[] sendBytes = Encoding.ASCII.GetBytes("!LOG RD OFF \r\n"); await client.SendAsync(sendBytes, sendBytes.Length).ConfigureAwait(false); } using (var ftp = new FtpClient()) { ftp.Host = this.RemoteAddress.ToString(); await ftp.ConnectAsync().ConfigureAwait(false); var configFiles = await ftp.GetNameListingAsync().ConfigureAwait(false); string lastRdFileName = configFiles.OrderByDescending(_ => _).FirstOrDefault(filename => filename.EndsWith(".rd")); if (lastRdFileName == null) { throw new InvalidOperationException("No RD file found."); } lastRdFileName = lastRdFileName.Replace('\\', '/'); var transferData = new FileTransferData { MonitoredFolderPath = string.Format(@"\\{0}", this.RemoteAddress), FileName = this.SequenceId + ".rd", MachineName = Environment.MachineName, DestinationFolderPath = this.SaveFolderAbsolutePath }; this.LastTransferredFile = transferData; using (var source = await ftp.OpenReadAsync(lastRdFileName).ConfigureAwait(false)) using (var destination = File.Open(Path.Combine(transferData.DestinationFolderPath, transferData.FileName), FileMode.OpenOrCreate)) { await IOHelper.Copy(source, destination, progressCallback: (copied, total) => { this.LastTransferredFile = new FileTransferData(transferData) { CopiedBytes = copied, TotalBytes = total }; }) .ConfigureAwait(false); } } } finally { using (var client = new UdpClient(new IPEndPoint(this.RemoteAddress, this.UdpSenderPort))) { byte[] sendBytes = Encoding.ASCII.GetBytes("!LOG RD ON \r\n"); client.Send(sendBytes, sendBytes.Length); } this.IsTransferring = false; } }); }
public async Task SendFileAsync(FileTransferData data) { await _daemon.SendFileAsync(data); }
private async Task TransferFile(string sourceFilePath, CancellationToken ct) { if (string.IsNullOrEmpty(sourceFilePath)) { throw new ArgumentNullException("sourceFilePath"); } var sourceFilename = Path.GetFileName(sourceFilePath); if (string.IsNullOrEmpty(sourceFilename)) { throw new InvalidOperationException("sourceFilePath does not contain a filename."); } try { var results = await Task.WhenAll( this.Settings.DestinationFolders.Select( async destinationFolder => { try { string destinationFilePath = GetDestinationFilePath(sourceFilePath, destinationFolder); await IOHelper.Copy(sourceFilePath, destinationFilePath, OverwriteMode.OverwriteIfDifferent, CopyOptions.AllowHardLinkCreation | CopyOptions.DisableBuffering, ct, (copiedBytes, totalBytes) => { var fileProgressData = new FileTransferData { MachineName = Environment.MachineName, MonitoredFolderPath = _monitor.Path, DestinationFolderPath = destinationFolder, FileName = Path.GetFileName(sourceFilePath), CopiedBytes = copiedBytes, TotalBytes = totalBytes }; _fileTransferSubject.OnNext(fileProgressData); }).ConfigureAwait(false); return(true); } catch (OperationCanceledException) { return(false); } catch (Exception ex) { // level set to Trace because it generates a lot of events Log.Trace().Exception(ex).Write(); long fileLength = 0; try { fileLength = new FileInfo(sourceFilePath).Length; } catch { } var errorData = new FileTransferData { MachineName = Environment.MachineName, DestinationFolderPath = destinationFolder, MonitoredFolderPath = _monitor.Path, FileName = Path.GetFileName(sourceFilePath), TotalBytes = fileLength, Exception = ex }; _fileTransferSubject.OnNext(errorData); return(false); } })).ConfigureAwait(false); if (!ct.IsCancellationRequested && results.All(result => result)) { File.Delete(sourceFilePath); } } catch (Exception ex) { Log.Warn().Exception(ex).Write(); } }