diff --git a/FileSplitter/FileSplitter.csproj b/FileSplitter/FileSplitter.csproj index e052a83..2792840 100644 --- a/FileSplitter/FileSplitter.csproj +++ b/FileSplitter/FileSplitter.csproj @@ -7,6 +7,24 @@ enable FileSplitter.Console FileSplitter + FileSplitter + ANB Software File Splitter Console + 2023.04.09 + Alexander Babaev + ANB Software File Splitter + Console App for ANB Software File Splitter. Split and join any file. + Alexander Babaev + https://git.babaev-an.ru/babaev-an/FileSplitter + https://git.babaev-an.ru/babaev-an/FileSplitter.git + ru + + + + + + + + diff --git a/FileSplitter/Program.cs b/FileSplitter/Program.cs index f83987b..fef5bdd 100644 --- a/FileSplitter/Program.cs +++ b/FileSplitter/Program.cs @@ -1,66 +1,128 @@ -//Приветственное сообщение -Console.WriteLine("ANB Software Делитель файлов"); -Console.WriteLine("в. 2023.04.08"); +using System.Reflection; -//Вывожу помощь -Help(); +using anbs_cp.Classes; -//Команда -string command; +using FileSplitter.Shared.Classes; +using FileSplitter.Shared.Enums; -//Начинаю цикл -do +string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty; + +//Инициализирую список параметров +ConsoleParamsParser consoleParser = new(Environment.GetCommandLineArgs()); + +//Приветственное сообщение +Console.WriteLine("********************************************************************************"); +Console.WriteLine($"\t{Localization.AppTitle}"); +Console.WriteLine($"\t{string.Format(Localization.AppVersion, assemblyVersion)}"); +Console.WriteLine( + $"\t{string.Format(Localization.AppCopyrights, DateTime.Now.Year == 2023 ? "2023" : $"2023 - {DateTime.Now.Year}")}"); +Console.WriteLine("********************************************************************************"); + +//Прерываем, если нет параметров +if (!consoleParser.HasParam("split") && !consoleParser.HasParam("join")) { - //Запрос команды - Console.WriteLine("Введите команду:"); - - //Считывание команды - command = (Console.ReadLine() ?? "").ToLower(); - - //Выбор действия - switch (command) - { - ////Если команда "Шифровка" - //case "crypt" or "c": - // //Запускаю сценарий шифровки - // await CryptAsync(); - // break; - ////Если команда "Дешифровка" - //case "delete" or "d": - // //Запускаю сценарий дешифровки - // await DecryptAsync(); - // break; - ////Если команда "Установочные файлы" - //case "ifiles" or "i": - // //Запускаю сценарий создания установочных файлов - // await CreateInstallFilesInfoAsync(); - // break; - ////Если команда "Помощь" - //case "help" or "h": - // //Запускаю сценарий помощи - // Help(); - // break; - //Если что-то другое - default: - //Вывожу сообщение об ошибке, если команда не "Выход" - if (command is not ("exit" or "e")) - Console.WriteLine("Команда не опознана! Повторите попытку ещё раз, введите [h]elp для помощи или введите [e]xit для выхода..."); - break; - } -} while (command is not ("exit" or "e")); - -static void SplitFile(string path) -{ - + Console.WriteLine(Localization.MessageNoParameters); + return; } -//Информация о работе с программой -static void Help () +//Разделение файлов +if (consoleParser.HasParam("split")) + FileSplit(consoleParser); + +//Соединение файлов +if (consoleParser.HasParam("join")) + FileJoin(consoleParser); + +//Функция разделения файлов +static void FileSplit (ConsoleParamsParser @params) { - //Публикую сообщение о работе с программой - Console.WriteLine("Информация о работе с программой:\n\t" + - "[c]rypt - шифровка архива\n\t" + - "[d]ecrypt - дешифровка архива\n\t" + - "[i]files - создание списка установочных файлов\n\t" + - "[e]xit - Выход из программы\n\t[h]elp - Повторный вывод этого сообщения."); + //Проверяю наличие параметров + if (!@params.HasParam("-fn") || !@params.HasParam("-td") || !@params.HasParam("-ps")) + { + //- вывожу сообщение + Console.WriteLine(Localization.MessageNoParametersForSplit); + + //- прерываю + return; + } + + //Получаю параметры + //- имя исходного файла + string fileName = @params.GetValue("-fn") ?? string.Empty; + //- папка для сохранения разбиения + string targetDir = @params.GetValue("-td") ?? string.Empty; + //- размер части + long partSize = TypeConverter.StrToInt64(@params.GetValue("-ps") ?? string.Empty); + //- параметры + List options = new(); + + //Проверяю параметры разбиения + //- отключена ли проверка хэша + if (@params.HasParam("/NoCheckHash")) + options.Add(FileSplitOptions.fsoNoCheckHash); + //- нужно ли удалять исходный файл + if (@params.HasParam("/DeleteSource")) + options.Add(FileSplitOptions.fsoDeleteSourceFileAfterSplit); + //- нужно ли шифровать файл информации + if (@params.HasParam("/EncryptInfoFile")) + options.Add(FileSplitOptions.fsoEncryptInfoFile); + + //Функция прогресса + #pragma warning disable CS8622 + FileSplitterClass.OnProgress += OnProgress; + #pragma warning restore CS8622 + + //Выполняю разбиение + FileSplitterClass.SplitFile(fileName, targetDir, partSize, options.AsReadOnly()); +} + +//Функция объединения +static void FileJoin (ConsoleParamsParser @params) +{ + //Проверяю наличие параметров + if (!@params.HasParam("-ifn") || !@params.HasParam("-tfn")) + { + //- вывожу сообщение + Console.WriteLine(Localization.MessageNoParametersForSplit); + + //- прерываю + return; + } + + //Получаю параметры + //- имя файла с информацией о разбиении + string infoFileName = @params.GetValue("-ifn") ?? string.Empty; + //- имя целевого файла + string targetFileName = @params.GetValue("-tfn") ?? string.Empty; + //- параметры + List options = new(); + + //Проверяю параметры разбиения + //- отключена ли проверка хэша + if (@params.HasParam("/NoCheckHash")) + options.Add(FileJoinOptions.fjoNoCheckHash); + //- нужно ли удалять исходные файлы + if (@params.HasParam("/DeleteSource")) + options.Add(FileJoinOptions.fjoDeleteSourceFilesAfterJoin); + //- нужно ли дешифровать файл информации + if (@params.HasParam("/DecryptInfoFile")) + options.Add(FileJoinOptions.fjoInfoFileIsEncrypted); + //- нужно ли отключить проверку версии файла информации + if (@params.HasParam("/IgnoreVersion")) + options.Add(FileJoinOptions.fjoIgnoreSupportedScriptVersion); + + //Функция прогресса + #pragma warning disable CS8622 + FileSplitterClass.OnProgress += OnProgress; + #pragma warning restore CS8622 + + //Выполняю объединение + FileSplitterClass.JoinFile(infoFileName, targetFileName, options.AsReadOnly()); +} + +//Функция вывода прогресса +static void OnProgress (object sender, FileSplitterOnProgress args) +{ + //Вывод сообщения в консоль + Console.WriteLine(args.Message); } \ No newline at end of file diff --git a/FileSplitterProj.sln.DotSettings b/FileSplitterProj.sln.DotSettings new file mode 100644 index 0000000..a08159e --- /dev/null +++ b/FileSplitterProj.sln.DotSettings @@ -0,0 +1,7 @@ + + True + True + True + True + True + True \ No newline at end of file diff --git a/FileSplitterShared/Classes/FileSplitInfo.cs b/FileSplitterShared/Classes/FileSplitInfo.cs index 1a9d90b..d961601 100644 --- a/FileSplitterShared/Classes/FileSplitInfo.cs +++ b/FileSplitterShared/Classes/FileSplitInfo.cs @@ -5,20 +5,27 @@ namespace FileSplitter.Shared.Classes; /// /// Информация о разбиении /// -public class FileSplitInfo +public sealed class FileSplitInfo { + public FileSplitInfo() + { + SplitFiles = new(); + TargetFile = new TargetFileInfo(); + FileSplitterVersion = FileSplitterConstants.CurrentSplitterVersion; + } + /// /// Версия программы, необходимая для сборки файла /// - public string? FileSplitterVersion { get; set; } + public string FileSplitterVersion { get; set; } /// /// Информация о собираемом файле /// - public ITargetFileInfo? TargetFile { get; set; } + public TargetFileInfo TargetFile { get; set; } /// /// Информация о частях файла /// - public List? SplitFiles { get; set; } + public List SplitFiles { get; set; } } \ No newline at end of file diff --git a/FileSplitterShared/Classes/FileSplitterClass.cs b/FileSplitterShared/Classes/FileSplitterClass.cs new file mode 100644 index 0000000..c0627b7 --- /dev/null +++ b/FileSplitterShared/Classes/FileSplitterClass.cs @@ -0,0 +1,346 @@ +using System.Collections; +using System.Collections.ObjectModel; +using System.Text; + +using anbs_cp.Classes; +using anbs_cp.Classes.Encrypt; + +using FileSplitter.Shared.Enums; +using FileSplitter.Shared.Interfaces; + +using Newtonsoft.Json; + +namespace FileSplitter.Shared.Classes; + +/// +/// Класс операций +/// +public static class FileSplitterClass +{ + /// + /// Событие прогресса + /// + public static event EventHandler? OnProgress; + + /// + /// Разделение файла на части + /// + /// Имя файла для разделения + /// Папка, в которую нужно сохранить файлы + /// Размер части в байтах + /// Параметры разбиения + public static void SplitFile (string fileName, string targetDir, long partSize, ReadOnlyCollection options) + { + //Задаю обработчик для распаковки + EventHandler? onProgressEvent = OnProgress; + + //Инициализирующее сообщение + onProgressEvent?.Invoke(null, + new(0, 0, + string.Format(Localization.MessageStartSplit, fileName, + new FileSizeConverter(Localization.FileSizeStrings).Convert(partSize), + targetDir + ))); + + //Создаю результат + FileSplitInfo splitInfo = new() + { + FileSplitterVersion = FileSplitterConstants.CurrentSplitterVersion + }; + + //Если целевая папка не создана + if (!Directory.Exists(targetDir)) + //- то создаём её + Directory.CreateDirectory(targetDir); + + //Получаю размер текущего файла + long fileSize = FileExtension.FileSize(fileName); + + //Получаю информацию о целевом файле + splitInfo.TargetFile = new() + { + FileName = Path.GetFileName(fileName), + FileSize = fileSize, + FileHash = new FileHash(fileName).Hash, + // ReSharper disable once PossibleLossOfFraction + SplitCount = (long)Math.Round(fileSize / (decimal)partSize, MidpointRounding.ToPositiveInfinity) + }; + + //Открываю файл + BinaryReader fileReader = new(File.Open(fileName, FileMode.Open)); + + //Разделяю файлы + for (int i = 0; i < splitInfo.TargetFile.SplitCount; i++) + { + //Сообщение прогресса + onProgressEvent?.Invoke(null, + new(i + 1, splitInfo.TargetFile.SplitCount, + string.Format(Localization.MessageSplitFilePart, i + 1, splitInfo.TargetFile.SplitCount))); + + //Имя части + string partName = $"{Path.GetFileName(fileName)}.part{i + 1}.fsf"; + //Полный путь к файлу части + string partFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{partName}"; + + //Смещение части от начала исходного файла + int startPos = (int)(i * partSize); + + //Размер части + long bufferSize = fileSize - startPos > 0 ? partSize : partSize + (fileSize - startPos); + + //Считываю значения + byte[] buffer = fileReader.ReadBytes((int)bufferSize); + + //Записываю значение в файл + //- открываю файл + BinaryWriter fileWriter = new(File.Create(partFileName, (int)bufferSize)); + //- записываю файл + fileWriter.Write(buffer); + //- закрываю файл + fileWriter.Close(); + + //Создаю информацию о части + SplitFile fileInfo = new() + { + Num = i + 1, + Offset = startPos, + Size = new FileInfo(partFileName).Length, + Hash = new FileHash(partFileName).Hash + }; + + //Добавляю в файл информации + splitInfo.SplitFiles.Add(fileInfo); + } + + //Закрываю исходный файл + fileReader.Close(); + //- и освобождаю память + fileReader.Dispose(); + + //Инициализирующее сообщение + onProgressEvent?.Invoke(null, + new(0, 0, + string.Format(Localization.MessageSplitComplete, fileName))); + + //Проверка сумм + if (!options.Contains(FileSplitOptions.fsoNoCheckHash)) + //- и если не прошли проверку + if (!CheckHash(targetDir, Path.GetFileName(fileName), splitInfo.SplitFiles)) + //- то удаляем файлы разбиения + DeleteSplitFiles(Path.GetFileName(fileName), targetDir, splitInfo.TargetFile.SplitCount); + + //Имя файла информации о разбиении + string reportFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{Path.GetFileName(fileName)}.fsi"; + + //Записываю информацию о разбиении + //- создаю файл + StreamWriter writer = new(reportFileName, Encoding.UTF8, new() { Access = FileAccess.Write, Mode = FileMode.Create }); + //- создаю данные для записи файла + string data = options.Contains(FileSplitOptions.fsoEncryptInfoFile) + ? StringEncrypt.Encrypt(JsonConvert.SerializeObject(splitInfo)) + : JsonConvert.SerializeObject(splitInfo); + //- записываю в файл + writer.WriteLine(data); + //- закрываю файл + writer.Close(); + //- освобождаю память + writer.Dispose(); + + //Если в опциях активирована опция удаления исходного файла + if (options.Contains(FileSplitOptions.fsoDeleteSourceFileAfterSplit)) + //- то удаляю его + File.Delete(fileName); + } + + /// + /// Объединение разъединенного файла + /// + /// Имя файла с информацией о разделении + /// Целевой файл + /// Параметры объединения + public static void JoinFile (string infoFileName, string targetFileName, ReadOnlyCollection options) + { + //Задаю обработчик для распаковки + EventHandler? onProgressEvent = OnProgress; + + //Инициализирующее сообщение + onProgressEvent?.Invoke(null, + new(0, 0, + string.Format(Localization.MessageStartJoin, infoFileName, targetFileName))); + + //Открываю файл для чтения + StreamReader reader = new(infoFileName, Encoding.UTF8); + + //Читаю строку + string tLine = reader.ReadLine() ?? "{}"; + + //Освобождаю reader + reader.Close(); + reader.Dispose(); + + //Содержимое файла информации о разбиении + string jsonData = options.Contains(FileJoinOptions.fjoInfoFileIsEncrypted) + ? StringEncrypt.Decrypt(tLine) + : tLine; + + //Создаю переменную для информации о разбиении + FileSplitInfo splitInfo = new(); + + try + { + //Получаю информацию о разбиении + splitInfo = JsonConvert.DeserializeObject(jsonData) ?? splitInfo; + } + catch (Exception) + { + onProgressEvent?.Invoke(null, + new(0, 0, Localization.MessageJoinUnknownFile)); + Environment.Exit(2); + } + + //Проверяю версию + if (!options.Contains(FileJoinOptions.fjoIgnoreSupportedScriptVersion) && + !FileSplitterConstants.SupportSplitterVersion.Contains(splitInfo.FileSplitterVersion)) + { + //Вывожу сообщение + onProgressEvent?.Invoke(null, + new(0, 0, string.Format(Localization.MessageJoinUnsupportedFile, splitInfo.FileSplitterVersion))); + + //Прерываю + return; + } + + //Получаю папку с разделёнными файлами + string sourceDir = LikeDelphi.IncludeTrailingBackslash(Path.GetDirectoryName(infoFileName) ?? ""); + + //Проверяю хэш + if (!options.Contains(FileJoinOptions.fjoNoCheckHash) && !CheckHash(sourceDir, + Path.GetFileName(splitInfo.TargetFile.FileName), splitInfo.SplitFiles)) + { + //Вывожу сообщение + onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinHashError)); + + //Прерываю + return; + } + + //Открываю файл + BinaryWriter fileWriter = new(File.Create(targetFileName, (int)splitInfo.TargetFile.FileSize)); + + //Объединяю файлы + for (int i = 1; i <= splitInfo.TargetFile.SplitCount; i++) + { + //Вывожу сообщение + onProgressEvent?.Invoke(null, + new(i, splitInfo.TargetFile.SplitCount, + string.Format(Localization.MessageJoinFilePart, i, splitInfo.TargetFile.SplitCount))); + + //Имя файла части + string partFileName = $"{sourceDir}{Path.GetFileName(splitInfo.TargetFile.FileName)}.part{i}.fsf"; + + //Параметры части + ISplitFile partInfo = splitInfo.SplitFiles.FirstOrDefault(file => file.Num == i) ?? new SplitFile(); + + //Читаю часть + //- открываю файл для чтения + BinaryReader fileReader = new(File.Open(partFileName, FileMode.Open)); + //- считываю содержимое + byte[] buffer = fileReader.ReadBytes((int)partInfo.Size); + //- закрываю файл + fileReader.Close(); + //- освобождаю память + fileReader.Dispose(); + + //Записываю часть в общий файл + fileWriter.Write(buffer); + } + + //Закрываю целевой файл + fileWriter.Close(); + //Освобождаю память + fileWriter.Dispose(); + + //Вывожу сообщение + onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinComplete)); + + //Удаляю разделённые файлы + if (options.Contains(FileJoinOptions.fjoDeleteSourceFilesAfterJoin)) + DeleteSplitFiles(splitInfo.TargetFile.FileName, sourceDir, splitInfo.TargetFile.SplitCount); + } + + /// + /// Удаление разделённых файлов + /// + /// Исходное имя файла (без пути!) + /// Целевая директория + /// Число разбиения + private static void DeleteSplitFiles (string fileName, string targetDir, long splitCount) + { + //Перебираю части + for (int i = 1; i < splitCount; i++) + { + //Имя части + string partName = $"{fileName}.part{i}.fsf"; + //Полный путь к файлу части + string partFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{partName}"; + + //Удаляю файл + File.Delete(partFileName); + } + + //Имя файла информации о разбиении + string reportFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{Path.GetFileName(fileName)}.fsi"; + + //Удаляю файл информации + File.Delete(reportFileName); + } + + /// + /// Проверяет соответствие хэша файлов + /// + /// Базовая папка с файлами + /// Базовое имя файлов + /// Список параметров файлов разбиения + /// Прошли ли файлы проверку + private static bool CheckHash (string baseDir, string baseName, List fileList) + { + //Задаю обработчик для распаковки + EventHandler? onProgressEvent = OnProgress; + + //Инициализирующее сообщение + onProgressEvent?.Invoke(null, + new(0, 0, + Localization.MessageHashCheckStart)); + + //Перебираю все части + foreach (SplitFile file in fileList) + { + //Полный путь к файлу части + string partFileName = $"{LikeDelphi.IncludeTrailingBackslash(baseDir)}{baseName}.part{file.Num}.fsf"; + + //Получаю хэш + IStructuralEquatable fileHashEq = new FileHash(partFileName).Hash; + + //Если не равен + if (!fileHashEq.Equals(file.Hash, StructuralComparisons.StructuralEqualityComparer)) + { + //- то сообщаю + onProgressEvent?.Invoke(null, + new(0, 0, + string.Format(Localization.MessageHashCheckFail, partFileName))); + + //- и прерываю + return false; + } + } + + //Везде хэш был равен + //- выдаю сообщение + onProgressEvent?.Invoke(null, + new(0, 0, + Localization.MessageHashCheckComplete)); + + //- и возвращаю результат + return true; + } +} \ No newline at end of file diff --git a/FileSplitterShared/Classes/FileSplitterConstants.cs b/FileSplitterShared/Classes/FileSplitterConstants.cs new file mode 100644 index 0000000..1192853 --- /dev/null +++ b/FileSplitterShared/Classes/FileSplitterConstants.cs @@ -0,0 +1,17 @@ +namespace FileSplitter.Shared.Classes; + +/// +/// Неизменяемые константы программы +/// +public static class FileSplitterConstants +{ + /// + /// Текущая версия информационного файла + /// + public static string CurrentSplitterVersion = "20230409"; + + /// + /// Все поддерживаемые версии информационного файла + /// + public static string[] SupportSplitterVersion = { "20230409" }; +} \ No newline at end of file diff --git a/FileSplitterShared/Classes/FileSplitterOnProgress.cs b/FileSplitterShared/Classes/FileSplitterOnProgress.cs new file mode 100644 index 0000000..7143248 --- /dev/null +++ b/FileSplitterShared/Classes/FileSplitterOnProgress.cs @@ -0,0 +1,35 @@ +namespace FileSplitter.Shared.Classes; + +/// +/// Параметры события OnProgress +/// +public class FileSplitterOnProgress: EventArgs +{ + /// + /// Конструктор + /// + /// Текущий прогресс + /// Максимальные прогресс + /// Сообщение + public FileSplitterOnProgress (long current, long total, string message) + { + CurrentProgress = current; + MaxProgress = total; + Message = message; + } + + /// + /// Текущий прогресс + /// + public long CurrentProgress { get; } + + /// + /// Максимальные прогресс + /// + public long MaxProgress { get; } + + /// + /// Сообщение + /// + public string Message { get; } +} \ No newline at end of file diff --git a/FileSplitterShared/Classes/Localization.cs b/FileSplitterShared/Classes/Localization.cs new file mode 100644 index 0000000..a3fde19 --- /dev/null +++ b/FileSplitterShared/Classes/Localization.cs @@ -0,0 +1,31 @@ +namespace FileSplitter.Shared.Classes; + +public static class Localization +{ + //Параметры приложения + public const string AppTitle = "ANB Software Делитель файлов"; + public const string AppVersion = "Версия: {0}"; + public const string AppCopyrights = "Авторские права (C) {0}, Александр Бабаев."; + + //Сообщения + public const string MessageNoParameters = + "Нет параметров. Информацию о работе с программой смотрите в файле \"Help\\Russian\\Console.html\""; + public const string MessageNoParametersForSplit = + "Не заданы параметры разбиения. Информацию о работе с программой смотрите в файле \"Help\\Russian\\Console.html\""; + public const string MessageStartSplit = "Запущено разбиение файла {0} на части размером {1} и сохранением их в директории {2}."; + public const string MessageSplitFilePart = "Идёт обработка части {0} из {1}..."; + public const string MessageSplitComplete = "Разбиение файла {0} завершено!"; + public const string MessageHashCheckStart = "Начинаю проверку хэша разбиения"; + public const string MessageHashCheckFail = "К сожалению, файл \"{0}\" не прошёл проверку хэша!"; + public const string MessageHashCheckComplete = "Проверка хэша завершена!"; + public const string MessageStartJoin = "Запущено объединение файлов, заданных файлом информации {0}, в файл {1}."; + public const string MessageJoinUnsupportedFile = "К сожалению, версия файла информации {0} не поддерживается!"; + public const string MessageJoinUnknownFile = "Не могу прочитать файл информации! Возможно он зашифрован?"; + public const string MessageJoinHashError = "К сожалению, разделённые файлы не прошли проверку. Возможно они повреждены?"; + public const string MessageJoinFilePart = "Идёт обработка части {0} из {1}..."; + public const string MessageJoinComplete = "Объединение файла {0} завершено!"; + + + //Константы размеров + public static readonly string[] FileSizeStrings = { "байт", "Кб", "Мб", "Гб", "Тб" }; +} \ No newline at end of file diff --git a/FileSplitterShared/Classes/SplitFile.cs b/FileSplitterShared/Classes/SplitFile.cs index fa68456..6d069e4 100644 --- a/FileSplitterShared/Classes/SplitFile.cs +++ b/FileSplitterShared/Classes/SplitFile.cs @@ -5,12 +5,12 @@ namespace FileSplitter.Shared.Classes; /// /// Разделенный файл /// -public class SplitFile: ISplitFile +public sealed class SplitFile: ISplitFile { /// /// Порядок части /// - public byte Num { get; set; } + public int Num { get; set; } /// /// Размер части diff --git a/FileSplitterShared/Classes/TargetFileInfo.cs b/FileSplitterShared/Classes/TargetFileInfo.cs index 2ce6d66..829db58 100644 --- a/FileSplitterShared/Classes/TargetFileInfo.cs +++ b/FileSplitterShared/Classes/TargetFileInfo.cs @@ -5,12 +5,21 @@ namespace FileSplitter.Shared.Classes; /// /// Информация о целевом файле /// -public class TargetFileInfo: ITargetFileInfo +public sealed class TargetFileInfo: ITargetFileInfo { + /// + /// Конструктор + /// + internal TargetFileInfo() + { + FileName = string.Empty; + FileHash = new byte[]{}; + } + /// /// Имя файла /// - public string? FileName { get; set; } + public string FileName { get; set; } /// /// Размер файла @@ -20,10 +29,10 @@ public class TargetFileInfo: ITargetFileInfo /// /// md5-сумма файла для проверки /// - public byte[]? FileHash { get; set; } + public byte[] FileHash { get; set; } /// /// Количество частей /// - public byte SplitCount { get; set; } + public long SplitCount { get; set; } } \ No newline at end of file diff --git a/FileSplitterShared/Enums/FileJoinOptions.cs b/FileSplitterShared/Enums/FileJoinOptions.cs new file mode 100644 index 0000000..5c7a910 --- /dev/null +++ b/FileSplitterShared/Enums/FileJoinOptions.cs @@ -0,0 +1,27 @@ +namespace FileSplitter.Shared.Enums; + +/// +/// Опции объединения файла +/// +public enum FileJoinOptions +{ + /// + /// Не проверять контрольную сумму перед началом объединения + /// + fjoNoCheckHash = 0, + + /// + /// Json-Файл информации о разбиении зашифрован + /// + fjoInfoFileIsEncrypted = 1, + + /// + /// Удалить исходные файлы после объединения + /// + fjoDeleteSourceFilesAfterJoin = 2, + + /// + /// Игнорировать не поддерживаемую версию файла информации + /// + fjoIgnoreSupportedScriptVersion = 3 +} \ No newline at end of file diff --git a/FileSplitterShared/Enums/FileSplitOptions.cs b/FileSplitterShared/Enums/FileSplitOptions.cs new file mode 100644 index 0000000..e2d95ae --- /dev/null +++ b/FileSplitterShared/Enums/FileSplitOptions.cs @@ -0,0 +1,22 @@ +namespace FileSplitter.Shared.Enums; + +/// +/// Опции разделения файла +/// +public enum FileSplitOptions +{ + /// + /// Не проверять контрольную сумму после создания всех частей + /// + fsoNoCheckHash = 0, + + /// + /// Шифровать json-Файл информации о разбиении + /// + fsoEncryptInfoFile = 1, + + /// + /// Удалить исходный файл после разбиения + /// + fsoDeleteSourceFileAfterSplit = 2 +} \ No newline at end of file diff --git a/FileSplitterShared/FileSplitterShared.csproj b/FileSplitterShared/FileSplitterShared.csproj index de61e59..c96047f 100644 --- a/FileSplitterShared/FileSplitterShared.csproj +++ b/FileSplitterShared/FileSplitterShared.csproj @@ -8,4 +8,9 @@ FileSplitter.Shared + + + + + diff --git a/FileSplitterShared/Interfaces/ISplitFile.cs b/FileSplitterShared/Interfaces/ISplitFile.cs index b59bc7e..ee5db6a 100644 --- a/FileSplitterShared/Interfaces/ISplitFile.cs +++ b/FileSplitterShared/Interfaces/ISplitFile.cs @@ -8,7 +8,7 @@ public interface ISplitFile /// /// Порядок части /// - public byte Num { get; set; } + public int Num { get; set; } /// /// Размер части diff --git a/FileSplitterShared/Interfaces/ITargetFileInfo.cs b/FileSplitterShared/Interfaces/ITargetFileInfo.cs index 98ad5e7..bd25c81 100644 --- a/FileSplitterShared/Interfaces/ITargetFileInfo.cs +++ b/FileSplitterShared/Interfaces/ITargetFileInfo.cs @@ -8,7 +8,7 @@ public interface ITargetFileInfo /// /// Имя файла /// - public string? FileName { get; set; } + public string FileName { get; set; } /// /// Размер файла @@ -18,10 +18,10 @@ public interface ITargetFileInfo /// /// md5-сумма файла для проверки /// - public byte[]? FileHash { get; set; } + public byte[] FileHash { get; set; } /// /// Количество частей /// - public byte SplitCount { get; set; } + public long SplitCount { get; set; } } \ No newline at end of file diff --git a/output/x32/FileSplitter.exe b/output/x32/FileSplitter.exe new file mode 100644 index 0000000..be9bc54 Binary files /dev/null and b/output/x32/FileSplitter.exe differ diff --git a/output/x32/sni.dll b/output/x32/sni.dll new file mode 100644 index 0000000..5fc21ac Binary files /dev/null and b/output/x32/sni.dll differ