/
rezvich
/
Prik
Обзор
Документация
Войти
/
rezvich
/
Prik
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Infrastructure/Files/InputFileScanner.cs
70 строк
2 KB
waweda299
Прик
08 июн 2026, 15:52
08 июн 2026, 15:52
9ddc25e
Код
Авторство
О чём код?
//prik/Infrastructure/Files/InputFileScanner.cs using System.Collections.Concurrent; namespace prik.Infrastructure.Files { public interface IInputFileScanner { IReadOnlyList<FileInfo> ListReadyCsv(string inputDir, int settleSeconds); } public sealed class InputFileScanner : IInputFileScanner { private sealed record Obs(long Size, DateTime MTimeUtc, DateTime FirstSeenUtc); private readonly ConcurrentDictionary<string, Obs> _obs = new(StringComparer.OrdinalIgnoreCase); public IReadOnlyList<FileInfo> ListReadyCsv(string inputDir, int settleSeconds) { var now = DateTime.UtcNow; var dir = new DirectoryInfo(inputDir); if (!dir.Exists) { return Array.Empty<FileInfo>(); } var candidates = dir.EnumerateFiles("*", SearchOption.TopDirectoryOnly) .Where(f => !f.Name.StartsWith("~") && !f.Name.StartsWith(".")) .Where(f => string.Equals(f.Extension, ".csv", StringComparison.OrdinalIgnoreCase)) .ToList(); // purge disappeared var present = new HashSet<string>(candidates.Select(f => f.FullName), StringComparer.OrdinalIgnoreCase); foreach (var k in _obs.Keys) { if (!present.Contains(k)) { _obs.TryRemove(k, out _); } } var ready = new List<FileInfo>(); foreach (var f in candidates) { var key = f.FullName; var size = f.Length; var mtime = f.LastWriteTimeUtc; if (!_obs.TryGetValue(key, out var prev)) { _obs[key] = new Obs(size, mtime, now); continue; } if (size != prev.Size || mtime != prev.MTimeUtc) { _obs[key] = new Obs(size, mtime, now); continue; } if ((now - prev.FirstSeenUtc).TotalSeconds >= settleSeconds && size > 0) { ready.Add(f); } } return ready.OrderBy(f => f.Name, StringComparer.OrdinalIgnoreCase).ToList(); } } }