IDirectory first pass

This commit is contained in:
2023-01-08 13:33:33 -07:00
parent 9b9573093f
commit 0ef5b668e8
27 changed files with 772 additions and 865 deletions

View File

@ -1,8 +1,12 @@
using System.Text.Json;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Container
{
private record FilePair(string Path, string? Directory, bool IsUnique, List<string> Collection, Models.Item Item) { }
internal static DateTime[] GetContainerDateTimes(Models.Item[] filteredItems)
{
DateTime[] results;
@ -26,8 +30,7 @@ internal abstract class Container
foreach (Models.Item item in container.Items)
{
if (item.ImageFileHolder is not null
&& (item.Abandoned is null || !item.Abandoned.Value)
&& item.ValidImageFormatExtension
&& item.IsValidImageFormatExtension
&& !propertyConfiguration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered))
results.Add(item);
}
@ -55,9 +58,7 @@ internal abstract class Container
internal static Models.Container[] SortContainers(Properties.IPropertyConfiguration propertyConfiguration, string[] ignoreRelativePaths, bool argZeroIsConfigurationRootDirectory, string argZero, Models.Container[] containers)
{
List<Models.Container> results = new();
Models.Item[] filteredItems;
bool isIgnoreRelativePath;
List<int> collection = new();
for (int i = 1; i < 3; i++)
{
foreach (Models.Container container in containers)
@ -66,30 +67,145 @@ internal abstract class Container
continue;
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = GetFilterItems(propertyConfiguration, container);
if (!filteredItems.Any())
continue;
isIgnoreRelativePath = ignoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && IsIgnoreRelativePath(propertyConfiguration, ignoreRelativePaths, container.SourceDirectory);
if (i == 1 && isIgnoreRelativePath)
continue;
if (i == 2 && !isIgnoreRelativePath)
continue;
foreach (Models.Item item in filteredItems)
{
if (item.Property?.Id is null)
continue;
if (collection.Contains(item.Property.Id.Value))
{
if (i == 1)
continue;
continue;
}
collection.Add(item.Property.Id.Value);
}
results.Add(container);
}
}
return results.ToArray();
}
internal static List<Models.FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List<string[]> filesCollection)
{
int renamed;
List<Models.FilePair>? filePairs = null;
List<string[]>? jsonFilesCollection = null;
IReadOnlyDictionary<string, List<string>>? compareFileNamesToFiles = null;
IReadOnlyDictionary<string, List<string>> fileNamesToFiles = IDirectory.GetFilesKeyValuePairs(filesCollection);
for (int i = 0; i < int.MaxValue; i++)
{
renamed = 0;
jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension);
compareFileNamesToFiles = IDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
renamed += IDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
filePairs = IDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
renamed += IDirectory.MaybeMove(propertyConfiguration.RootDirectory, propertyConfiguration.ResultAllInOne, filePairs, aPropertySingletonDirectory, extension);
if (renamed == 0)
break;
}
if (filePairs is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
throw new NullReferenceException(nameof(filePairs));
return filePairs;
}
private static Models.Property? GetProperty(Models.FilePair filePair)
{
Models.Property? property;
if (filePair.Match is null)
property = null;
else
{
string json = File.ReadAllText(filePair.Match);
if (string.IsNullOrEmpty(json))
property = null;
else
property = JsonSerializer.Deserialize<Models.Property>(json);
}
return property;
}
private static void ParallelFor(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int length, Models.FilePair filePair, List<FilePair> results)
{
char directory;
string fileName;
bool abandoned = false;
Models.FileHolder sourceDirectoryFileHolder;
Models.Property? property = GetProperty(filePair);
Models.FileHolder imageFileInfo = new(filePair.Path);
bool? fileSizeChanged = property is not null ? property.FileSize != imageFileInfo.Length : null;
string relativePath = IPath.GetRelativePath(filePair.Path, length, forceExtensionToLower: true);
bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(imageFileInfo.ExtensionLowered);
bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime != imageFileInfo.LastWriteTime : null;
if (filePair.Match is not null)
sourceDirectoryFileHolder = new(filePair.Match);
else if (!filePair.IsUnique)
sourceDirectoryFileHolder = new(Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath, extension)));
else
{
fileName = Path.GetFileName(filePair.Path);
directory = IDirectory.GetDirectory(fileName);
sourceDirectoryFileHolder = new(Path.Combine(aPropertySingletonDirectory, propertyConfiguration.ResultAllInOne, directory.ToString(), $"{fileName}{extension}"));
}
if (imageFileInfo.LastWriteTime is not null && sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && imageFileInfo.LastWriteTime.Value != sourceDirectoryFileHolder.CreationTime.Value)
{
File.SetCreationTime(sourceDirectoryFileHolder.FullName, imageFileInfo.LastWriteTime.Value);
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
}
Models.Item item = new(sourceDirectoryFileHolder, relativePath, imageFileInfo, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
lock (results)
results.Add(new(filePair.Path, imageFileInfo.DirectoryName, filePair.IsUnique, filePair.Collection, item));
}
private static List<FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, List<Models.FilePair> filePairs)
{
List<FilePair> results = new();
int length = propertyConfiguration.RootDirectory.Length;
int maxDegreeOfParallelism = Environment.ProcessorCount;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
_ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(propertyConfiguration, aPropertySingletonDirectory, extension, length, filePairs[i], results));
return results;
}
internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory)
{
List<Models.Container> results = new();
string? directory;
List<Models.Item>? items;
Models.Container container;
const string extension = ".json";
const string fileSearchFilter = "*";
const string directorySearchFilter = "*";
Dictionary<string, List<Models.Item>> directoryToItems = new();
List<string[]> filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
foreach (string[] files in filesCollection)
{
if (!files.Any())
continue;
directory = Path.GetDirectoryName(files.First());
if (directory is null)
continue;
if (!directoryToItems.TryGetValue(directory, out items))
{
directoryToItems.Add(directory, new());
if (!directoryToItems.TryGetValue(directory, out items))
throw new Exception();
}
}
List<Models.FilePair> filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
List<FilePair> collection = GetFilePairs(propertyConfiguration, aPropertySingletonDirectory, extension, filePairs);
foreach (FilePair filePair in collection)
{
if (filePair.Directory is null)
continue;
if (!directoryToItems.TryGetValue(filePair.Directory, out items))
{
directoryToItems.Add(filePair.Directory, new());
if (!directoryToItems.TryGetValue(filePair.Directory, out items))
throw new Exception();
}
items.Add(filePair.Item);
}
foreach (KeyValuePair<string, List<Models.Item>> keyValuePair in directoryToItems)
{
if (!keyValuePair.Value.Any())
continue;
container = new(keyValuePair.Key, keyValuePair.Value);
results.Add(container);
}
return (collection.Count, results.ToArray());
}
}

View File

@ -42,90 +42,4 @@ internal abstract class FileHolder
}
}
internal static (int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List<string> topDirectories)
{
int result = 0;
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)> results = new();
string? parentDirectory;
string[] subDirectories;
string[] sourceDirectoryFiles;
List<string[]> fileCollections = new();
if (!topDirectories.Any())
{
if (!Directory.Exists(rootDirectory))
_ = Directory.CreateDirectory(rootDirectory);
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
}
for (int g = 1; g < 5; g++)
{
if (g == 4)
{
for (int i = fileCollections.Count - 1; i > -1; i--)
{
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
if (string.IsNullOrEmpty(parentDirectory))
continue;
results.Add(new(g, parentDirectory, fileCollections[i]));
fileCollections.RemoveAt(i);
}
}
else if (g == 2)
{
for (int i = fileCollections.Count - 1; i > -1; i--)
{
if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g)
break;
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
if (string.IsNullOrEmpty(parentDirectory))
continue;
results.Add(new(g, parentDirectory, fileCollections[i]));
fileCollections.RemoveAt(i);
}
}
else if (g == 3)
{
subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
if (reverse)
subDirectories = subDirectories.Reverse().ToArray();
foreach (string subDirectory in subDirectories)
{
sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (!topDirectories.Contains(subDirectory))
results.Add(new(g, subDirectory, sourceDirectoryFiles));
}
}
else if (g == 1)
{
sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
fileCollections.Add(sourceDirectoryFiles);
else
results.Add(new(g, rootDirectory, sourceDirectoryFiles));
if (reverse)
topDirectories.Reverse();
subDirectories = topDirectories.ToArray();
foreach (string subDirectory in subDirectories)
{
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
fileCollections.Add(sourceDirectoryFiles);
else
{
if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any())
results.Add(new(g, subDirectory, sourceDirectoryFiles));
else if (searchPattern == "*" && subDirectory != rootDirectory)
Directory.Delete(subDirectory);
}
}
fileCollections.Reverse();
}
else
throw new Exception();
}
return new(result, results);
}
}

View File

@ -23,4 +23,14 @@ public interface IContainer
static Models.Container[] SortContainers(Properties.IPropertyConfiguration propertyConfiguration, string[] ignoreRelativePaths, bool argZeroIsConfigurationRootDirectory, string argZero, Models.Container[] containers) =>
Container.SortContainers(propertyConfiguration, ignoreRelativePaths, argZeroIsConfigurationRootDirectory, argZero, containers);
List<FilePair> TestStatic_GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List<string[]> filesCollection) =>
Container.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
static List<FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List<string[]> filesCollection) =>
Container.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
(int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
GetContainers(propertyConfiguration, aPropertySingletonDirectory);
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
}

View File

@ -0,0 +1,39 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IDirectory
{
char TestStatic_GetDirectory(string fileName) =>
GetDirectory(fileName);
static char GetDirectory(string fileName) => fileName.Split('-').Length > 2 ? '-' : fileName.Split('.')[0][^1];
int TestStatic_GetDirectory(char directory) =>
GetDirectory(directory);
static int GetDirectory(char directory) => directory == '-' ? 10 : int.Parse(directory.ToString());
List<string[]> TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) =>
GetFilesCollection(directory, directorySearchFilter, fileSearchFilter);
static List<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) =>
XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter);
IReadOnlyDictionary<string, List<string>> TestStatic_GetFilesKeyValuePairs(List<string[]> filesCollection) =>
GetFilesKeyValuePairs(filesCollection);
static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(List<string[]> filesCollection) =>
XDirectory.GetFilesKeyValuePairs(filesCollection);
int TestStatic_LookForAbandoned(List<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension) =>
LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
static int LookForAbandoned(List<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension) =>
XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
int TestStatic_MaybeMove(string directory, string resultAllInOne, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
MaybeMove(directory, resultAllInOne, filePairs, jsonGroupDirectory, extension);
static int MaybeMove(string directory, string resultAllInOne, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
XDirectory.MaybeMove(directory, resultAllInOne, filePairs, jsonGroupDirectory, extension);
List<FilePair> TestStatic_GetFiles(List<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
static List<FilePair> GetFiles(List<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
}

View File

@ -23,9 +23,4 @@ public interface IFileHolder
static Models.FileHolder Refresh(Models.FileHolder fileHolder) =>
new(fileHolder.FullName);
(int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) TestStatic_GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List<string> topDirectories) =>
GetGroupCollection(rootDirectory, maxImagesInDirectoryForTopLevelFirstPass, reverse, searchPattern, topDirectories);
static (int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List<string> topDirectories) =>
FileHolder.GetGroupCollection(rootDirectory, maxImagesInDirectoryForTopLevelFirstPass, reverse, searchPattern, topDirectories);
}

View File

@ -0,0 +1,243 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract partial class XDirectory
{
private static int GetCeilingAverage(List<string[]> fileCollection)
{
List<int> counts = new();
foreach (string[] files in fileCollection)
counts.Add(files.Length);
int average = (int)Math.Ceiling(counts.Average());
return average;
}
private static List<string[]> GetFilesCollection(List<string[]> fileCollection, int ceilingAverage)
{
List<string[]> results = new();
foreach (string[] files in fileCollection)
{
if (files.Length < ceilingAverage)
results.Add(files);
}
foreach (string[] files in fileCollection)
{
if (files.Length >= ceilingAverage)
results.Add(files);
}
return results;
}
internal static List<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter)
{
List<string[]> results = new();
if (!fileSearchFilter.Contains('*'))
fileSearchFilter = string.Concat('*', fileSearchFilter);
if (!directorySearchFilter.Contains('*'))
directorySearchFilter = string.Concat('*', directorySearchFilter);
string[] directories = Directory.GetDirectories(directory, directorySearchFilter, SearchOption.TopDirectoryOnly);
foreach (string innerDirectory in directories)
results.Add(Directory.GetFiles(innerDirectory, fileSearchFilter, SearchOption.AllDirectories));
int ceilingAverage = GetCeilingAverage(results);
results = GetFilesCollection(results, ceilingAverage);
return results;
}
internal static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(List<string[]> filesCollection)
{
Dictionary<string, List<string>> results = new();
string fileName;
List<string>? collection;
foreach (string[] files in filesCollection)
{
foreach (string file in files)
{
fileName = Path.GetFileName(file);
if (!results.TryGetValue(fileName, out collection))
{
results.Add(fileName, new());
if (!results.TryGetValue(fileName, out collection))
throw new Exception();
}
collection.Add(file);
}
}
return results;
}
internal static int LookForAbandoned(List<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension)
{
string fileName;
List<string>? collection;
int length = extension.Length;
List<(string, string)> rename = new();
foreach (string[] files in jsonFilesCollection)
{
foreach (string file in files)
{
fileName = Path.GetFileName(file);
if (fileName.Length < length || !fileName.EndsWith(extension))
throw new Exception();
if (!fileNamesToFiles.TryGetValue(fileName[..^length], out collection))
rename.Add(new(file, string.Concat(file, ".del")));
}
}
foreach ((string from, string to) in rename)
{
if (File.Exists(to))
continue;
File.Move(from, to);
}
return rename.Count;
}
private static void IsNotUniqueLoop(string file, List<string> collection)
{
TimeSpan timeSpan;
FileInfo possibleFileInfo;
FileInfo fileInfo = new(file);
foreach (string possible in collection)
{
possibleFileInfo = new(possible);
if (possibleFileInfo.LastWriteTime == fileInfo.LastWriteTime && possibleFileInfo.Length == fileInfo.Length)
continue;
timeSpan = new(possibleFileInfo.LastWriteTime.Ticks - fileInfo.LastWriteTime.Ticks);
if (timeSpan.TotalMinutes < 2 && possibleFileInfo.Length == fileInfo.Length)
{
File.SetLastWriteTime(file, new DateTime[] { possibleFileInfo.LastWriteTime, fileInfo.LastWriteTime }.Min());
continue;
}
throw new Exception();
}
}
private static string? GetMatch(string file, List<string> collection)
{
string? result = null;
FileInfo possibleFileInfo;
List<long> lengths = new();
List<string> matches = new();
FileInfo fileInfo = new(file);
List<DateTime> creationTimes = new();
foreach (string possible in collection)
{
possibleFileInfo = new(possible);
lengths.Add(possibleFileInfo.Length);
creationTimes.Add(possibleFileInfo.CreationTime);
if (possibleFileInfo.CreationTime != fileInfo.LastWriteTime)
continue;
matches.Add(possible);
}
if (matches.Count == 1 || (lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
result = matches.First();
return result;
}
internal static List<FilePair> GetFiles(List<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles)
{
List<FilePair> results = new();
string? match;
string fileName;
bool uniqueFileName;
List<string>? collection;
foreach (string[] files in filesCollection)
{
foreach (string file in files)
{
fileName = Path.GetFileName(file);
if (!fileNamesToFiles.TryGetValue(fileName, out collection))
throw new Exception();
uniqueFileName = collection.Count == 1;
if (!uniqueFileName)
IsNotUniqueLoop(file, collection);
if (!compareFileNamesToFiles.TryGetValue(string.Concat(fileName, extension), out collection))
results.Add(new(file, uniqueFileName, new(), null));
else
{
if (!collection.Any())
results.Add(new(file, uniqueFileName, collection, null));
else if (uniqueFileName && collection.Count == 1)
results.Add(new(file, uniqueFileName, collection, collection.First()));
else
{
match = GetMatch(file, collection);
results.Add(new(file, uniqueFileName, collection, match));
}
}
}
}
return results;
}
private static void IsUniqueLoop(string resultAllInOne, string resultAllInOneDirectory, FilePair item, List<(string, string)> rename)
{
char directory;
string fileName;
foreach (string path in item.Collection)
{
if (path.Contains(resultAllInOne))
continue;
fileName = Path.GetFileName(path);
directory = IDirectory.GetDirectory(fileName);
rename.Add(new(path, Path.Combine(resultAllInOneDirectory, directory.ToString(), fileName)));
}
}
private static void IsNotUniqueLoop(string directory, string resultAllInOne, string jsonGroupDirectory, string extension, FilePair item, List<(string, string)> rename)
{
int length = directory.Length;
foreach (string path in item.Collection)
{
if (!path.Contains(resultAllInOne))
continue;
if (item.Match is null || path != item.Match)
continue;
rename.Add(new(path, string.Concat(jsonGroupDirectory, item.Path[length..], extension)));
}
}
internal static int MaybeMove(string directory, string resultAllInOne, List<FilePair> filePairs, string jsonGroupDirectory, string extension)
{
FileInfo? toFileInfo;
FileInfo fromFileInfo;
string checkDirectory;
List<(string, string)> rename = new();
string resultAllInOneDirectory = Path.Combine(jsonGroupDirectory, resultAllInOne);
foreach (FilePair item in filePairs)
{
if (item.IsUnique)
IsUniqueLoop(resultAllInOne, resultAllInOneDirectory, item, rename);
else
IsNotUniqueLoop(directory, resultAllInOne, jsonGroupDirectory, extension, item, rename);
}
foreach ((string from, string to) in rename)
{
toFileInfo = null;
checkDirectory = to;
fromFileInfo = new(from);
if (!fromFileInfo.Exists)
continue;
for (int i = 0; i < int.MaxValue; i++)
{
toFileInfo = new(checkDirectory);
if (toFileInfo.Directory is null)
continue;
if (!toFileInfo.Directory.Exists)
_ = Directory.CreateDirectory(toFileInfo.Directory.FullName);
if (checkDirectory.Length > 199)
throw new Exception();
if (!toFileInfo.Exists)
break;
else if (fromFileInfo.Length == toFileInfo.Length && fromFileInfo.LastWriteTime == toFileInfo.LastWriteTime)
checkDirectory = string.Concat(checkDirectory, ".del");
else
checkDirectory = string.Concat(checkDirectory, ".i");
}
File.Move(from, checkDirectory);
}
_ = IPath.DeleteEmptyDirectories(jsonGroupDirectory);
return rename.Count;
}
}