using System; using System.IO; using System.Linq; using System.Collections.Generic; namespace WinFormsApp1 { internal static class DirectoryAnalyser { public static List> FindFileDuplicates(string path) { string[] allFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); var nameDuplicates = allFiles .GroupBy(f => Path.GetFileName(f)) .Where(g => g.Count() > 1); var duplicates = new List>(); foreach (var group in nameDuplicates) { var curDuplicates = group .Select(f => new FileInfo(f)) .GroupBy(f => f.Length) .Where(g => g.Count() > 1); duplicates.AddRange(curDuplicates); } return duplicates; } public static List FindEmptySubdirectories(string path) { return Directory.GetDirectories(path, "*", SearchOption.AllDirectories) .Select(d => new DirectoryInfo(d)) .Where(d => d.GetDirectories().Length == 0 && d.GetFiles().Length == 0) .ToList(); } } } using System; using System.IO; using System.Linq; using System.Collections.Generic; namespace WinFormsApp1 { internal static class DirectoryCleaner { public static void DeleteDuplicateFiles(string path) { List> duplicates = DirectoryAnalyser.FindFileDuplicates(path); var deletionList = duplicates.Select(g => g.Skip(1)); foreach (var group in deletionList) { foreach (FileInfo file in group) file.Delete(); } } public static void DeleteEmptySubdirectories(string path) { List emptyDirectories; while ((emptyDirectories = DirectoryAnalyser.FindEmptySubdirectories(path)).Count > 0) { foreach (DirectoryInfo directory in emptyDirectories) directory.Delete(); } } } } using System; using System.Linq; using System.Globalization; using System.Collections.Generic; namespace WinFormsApp1 { internal class FileSorter { public bool UseSortingByDay { get; set; } public bool UseSortingByWeek { get; set; } public bool UseSortingByYear { get; set; } public FileSorter(bool useSortingByDay = true, bool useSortingByWeek = true, bool useSortingByYear = true) { UseSortingByDay = useSortingByDay; UseSortingByWeek = useSortingByWeek; UseSortingByYear = useSortingByYear; } public void Sort(string startPath) { SortInternalFiles(startPath); SortTopFiles(startPath); DirectoryCleaner.DeleteEmptySubdirectories(startPath); } public void SortTopFiles(string startPath) { var topFiles = new DirectoryInfo(startPath).GetFiles(); SortFiles(startPath, topFiles); } public void SortInternalFiles(string startPath) { var internalFiles = new List(); foreach (var subdir in new DirectoryInfo(startPath).GetDirectories()) { var files = Directory.GetFiles(subdir.FullName, "*.*", SearchOption.AllDirectories) .Select(d => new FileInfo(d)); internalFiles.AddRange(files); } SortFiles(startPath, internalFiles.ToArray()); } public void SortFiles(string startPath, FileInfo[] files) { var yearGroups = files.GroupBy(f => f.CreationTime.Year); foreach (var yearGroup in yearGroups) { string yearPath = UseSortingByYear ? Path.Combine(startPath, $"Year_{yearGroup.Key}") : startPath; var weekGroups = yearGroup.GroupBy(f => ISOWeek.GetWeekOfYear(f.CreationTime)); foreach (var weekGroup in weekGroups) { string weekPath = UseSortingByWeek ? Path.Combine(yearPath, $"Week_{weekGroup.Key}") : yearPath; var dayGroups = weekGroup.GroupBy(f => f.CreationTime.Day); foreach (var dayGroup in dayGroups) { string dayPath = UseSortingByDay ? Path.Combine(weekPath, $"Day_{dayGroup.Key}") : weekPath; if (!Directory.Exists(dayPath)) Directory.CreateDirectory(dayPath); foreach (var file in dayGroup) { string newFilePath = Path.Combine(dayPath, file.Name); file.MoveTo(newFilePath); } } } } } public bool CheckSorting(string path) { FileInfo[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories) .Select(f => new FileInfo(f)) .ToArray(); foreach (var file in files) { var creationTime = file.CreationTime; if (file.FullName.Contains("Year") && !file.FullName.Contains($"Year_{creationTime.Year}")) return false; if (file.FullName.Contains("Week") && !file.FullName.Contains($"Week_{ISOWeek.GetWeekOfYear(creationTime)}")) return false; if (file.FullName.Contains("Day") && !file.FullName.Contains($"Day_{creationTime.Day}")) return false; } return DirectoryAnalyser.FindEmptySubdirectories(path).Count == 0 && DirectoryAnalyser.FindFileDuplicates(path).Count == 0; } } } using System; using System.IO; using System.Linq; namespace WinFormsApp1 { internal static class TestingDirectoryGenerator { private static readonly Random _rand = new Random(); public static void Generate(string path) { GenerateUnsortedFiles(path); GenerateSortedFiles(path, 10); } private static void GenerateUnsortedFiles(string path) { for (int i = 0; i < 10; ++i) { string imgName = $"img-{i}.jpg"; string imgPath = Path.Combine(path, imgName); int bytesCount = _rand.Next(10, 500); byte[] imgBytes = new byte[bytesCount]; int day = _rand.Next(1, 25); int month = _rand.Next(1, 11); int year = _rand.Next(2019, 2023); var imgDateCreation = new DateTime(year, month, day); File.WriteAllBytes(imgPath, imgBytes); File.SetCreationTime(imgPath, imgDateCreation); } } private static void GenerateSortedFiles(string path, int imgStartNum) { var imgPaths = new List(); var years = new List(); var days = new List(); for (int i = 0; i <= 4; ++i) { for (int j = 0; j <= 4; ++j) { int year = _rand.Next(2018, 2022); int day = _rand.Next(23, 28); days.Add(day); years.Add(year); int month = _rand.Next(1, 11); var imgDateCreation = new DateTime(year, month, day); string imgName = $"img-{imgStartNum++}.jpg"; string imgDir = Path.Combine(path, $"Year_{year}", $"Day_{day}"); string imgPath = Path.Combine(imgDir, imgName); int bytesCount = _rand.Next(10, 500); byte[] imgBytes = new byte[bytesCount]; if (!Directory.Exists(imgDir)) Directory.CreateDirectory(imgDir); File.WriteAllBytes(imgPath, imgBytes); File.SetCreationTime(imgPath, imgDateCreation); imgPaths.Add(imgPath); } } var imgCopies = imgPaths .Take(imgPaths.Count / 2) .Select(t => new FileInfo(t)); foreach (var copy in imgCopies) { var acceptedDays = days .Where(t => t != copy.CreationTime.Day) .ToArray(); int index = acceptedDays.Length >= 2 ? _rand.Next(0, acceptedDays.Length - 1) : 0; int day = acceptedDays[index]; string parentDir = Directory.GetParent(copy.FullName).Parent.FullName; string imgDir = Path.Combine(parentDir, $"Day_{day}"); string dest = Path.Combine(imgDir, copy.Name); if (!Directory.Exists(imgDir)) Directory.CreateDirectory(imgDir); copy.CopyTo(dest); File.SetCreationTime(dest, copy.CreationTime); } } } }