コード例 #1
0
        public async Task OrganizeAsync(DicomOrganizerOptions options, CancellationToken cancellationToken)
        {
            var parallelism = options.Parallelism;

            if (!options.Directory.Exists)
            {
                throw new DicomOrganizeException($"Target directory does not exist: {options.Directory.FullName}");
            }

            var filesChannel = Channel.CreateUnbounded <FileInfo>(new UnboundedChannelOptions
            {
                SingleWriter = true,
                SingleReader = false
            });
            var tasks = new List <Task>
            {
                Task.Run(() => ProduceAsync(filesChannel.Writer, options, cancellationToken), cancellationToken)
            };

            for (var i = 0; i < parallelism; i++)
            {
                tasks.Add(
                    Task.Run(() => ConsumeAsync(filesChannel.Reader, options, cancellationToken), cancellationToken)
                    );
            }
            await Task.WhenAll(tasks).ConfigureAwait(false);
        }
コード例 #2
0
        private async Task ProduceAsync(ChannelWriter <FileInfo> filesChannelWriter, DicomOrganizerOptions dicomOrganizerOptions, CancellationToken cancellationToken)
        {
            var files = dicomOrganizerOptions.Files?.AsAsyncEnumerable() ?? _filesFromConsoleInputReader.Read(cancellationToken);

            await foreach (var file in files.WithCancellation(cancellationToken))
            {
                await filesChannelWriter.WriteAsync(file, cancellationToken).ConfigureAwait(false);
            }
        }
コード例 #3
0
        public Task ExecuteAsync(IConsole console, DicomOrganizerOptions dicomOrganizerOptions, CancellationToken cancellationToken)
        {
            var dicomTagParser    = new DicomTagParser();
            var folderNameCleaner = new FolderNameCleaner();
            var patternApplier    = new PatternApplier(dicomTagParser, folderNameCleaner);
            var errorHandler      = dicomOrganizerOptions.ErrorMode == ErrorMode.Continue
                ? (IErrorHandler) new ContinueErrorHandler(console)
                : new StopErrorHandler();
            var logger         = new Logger(console);
            var dicomOrganizer = new DicomOrganizer(patternApplier, errorHandler, logger, _filesFromConsoleInputReader);

            return(dicomOrganizer.OrganizeAsync(dicomOrganizerOptions, cancellationToken));
        }
コード例 #4
0
        private async Task ConsumeAsync(ChannelReader <FileInfo> filesChannelReader, DicomOrganizerOptions options, CancellationToken cancellationToken)
        {
            if (filesChannelReader == null)
            {
                throw new ArgumentNullException(nameof(filesChannelReader));
            }
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            while (await filesChannelReader.WaitToReadAsync(cancellationToken))
            {
                while (filesChannelReader.TryRead(out var file))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    await OrganizeFileAsync(file, options, cancellationToken);
                }
            }
        }
コード例 #5
0
        private async Task OrganizeFileAsync(FileInfo file, DicomOrganizerOptions options, CancellationToken cancellationToken)
        {
            var directory = options.Directory;
            var pattern   = options.Pattern;
            var action    = options.Action;

            DicomFile dicomFile;

            try
            {
                await using var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096);

                dicomFile = await DicomFile.OpenAsync(fileStream, FileReadOption.SkipLargeTags);
            }
            catch (DicomFileException e)
            {
                throw new DicomOrganizeException("Not a DICOM file: " + file.FullName, e);
            }

            string fileName;

            try
            {
                fileName = _patternApplier.Apply(dicomFile.Dataset, pattern);
            }
            catch (PatternException e)
            {
                throw new DicomOrganizeException($"Failed to apply pattern to file {file}", e);
            }

            var targetFile = new FileInfo(Path.Join(directory.FullName, fileName));

            if (!targetFile.Directory !.Exists)
            {
                var highestDirectoryName = HighestDirectoryNameDeterminer.Determine(fileName !);
                using (await KeyedSemaphore.LockAsync(highestDirectoryName, cancellationToken))
                {
                    try
                    {
                        if (!targetFile.Directory.Exists)
                        {
                            var directoryToCreate = targetFile.Directory !;

                            _ioPolicy.Execute(() => directoryToCreate.Create());
                        }
                    }
                    catch (IOException exception)
                    {
                        throw new DicomOrganizeException($"Failed to create directory {targetFile.Directory.FullName}", exception);
                    }
                }
            }

            if (file.FullName == targetFile.FullName)
            {
                _logger.WriteLine(targetFile.FullName);
                return;
            }

            if (targetFile.Exists)
            {
                var counter                        = 1;
                var targetFileName                 = targetFile.Name;
                var targetFileDirectoryName        = targetFile.Directory.FullName;
                var targetFileExtension            = targetFile.Extension;
                var targetFileNameWithoutExtension = targetFileName.Substring(0, targetFileName.Length - targetFileExtension.Length);

                while (targetFile.Exists)
                {
                    targetFileName = $"{targetFileNameWithoutExtension} ({counter++}){targetFile.Extension}";

                    targetFile = new FileInfo(Path.Join(targetFileDirectoryName, targetFileName));

                    if (file.FullName == targetFile.FullName)
                    {
                        _logger.WriteLine(targetFile.FullName);
                        return;
                    }
                }
            }

            try
            {
                switch (action)
                {
                case Action.Move:
                {
                    _ioPolicy.Execute(() => File.Move(file.FullName, targetFile.FullName));
                    _logger.WriteLine(targetFile.FullName);
                    break;
                }

                case Action.Copy:
                {
                    _ioPolicy.Execute(() => File.Copy(file.FullName, targetFile.FullName));
                    _logger.WriteLine(targetFile.FullName);
                    break;
                }
                }
            }
            catch (IOException e)
            {
                _errorHandler.Handle(new DicomOrganizeException($"Failed to {action.ToString().ToLowerInvariant()} {file}", e));
            }
        }