20230415
This commit is contained in:
parent
b2ea5c61d1
commit
3f774d751f
288
FileSplitter/Classes/Executor.cs
Normal file
288
FileSplitter/Classes/Executor.cs
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
using anbs_cp.Classes;
|
||||||
|
|
||||||
|
using FileSplitter.Shared.Classes;
|
||||||
|
using FileSplitter.Shared.Enums;
|
||||||
|
|
||||||
|
using static System.Console;
|
||||||
|
|
||||||
|
namespace FileSplitter.Console.Classes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс для выполнения разбиения, сборки, интерактивного режима
|
||||||
|
/// </summary>
|
||||||
|
internal static class Executor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Вывод прогресса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">Вызывающий объект</param>
|
||||||
|
/// <param name="args"><see cref="FileSplitterOnProgress"/></param>
|
||||||
|
private static void OnProgress (object sender, FileSplitterOnProgress args)
|
||||||
|
{
|
||||||
|
//Вывод сообщения в консоль
|
||||||
|
WriteLine(args.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Выполняю разбиение
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">Имя файла</param>
|
||||||
|
/// <param name="targetDir">Целевая папка с файлами разбиения</param>
|
||||||
|
/// <param name="partSize">Размер части</param>
|
||||||
|
/// <param name="silent">Тихий режим (без запросов)</param>
|
||||||
|
/// <param name="options">Параметры разбиения</param>
|
||||||
|
/// <returns>Код возврата</returns>
|
||||||
|
public static FsExitCode DoSplit (string fileName, string targetDir, long partSize, bool silent, List<FileSplitOptions> options)
|
||||||
|
{
|
||||||
|
//Функция прогресса
|
||||||
|
#pragma warning disable CS8622
|
||||||
|
FileSplitterClass.OnProgress += OnProgress;
|
||||||
|
#pragma warning restore CS8622
|
||||||
|
|
||||||
|
//Если не выбран тихий режим
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
//- получаю информацию о разбиении
|
||||||
|
TargetFileInfo fileInfo = FileSplitterClass.GetSplitFileInfo(fileName, partSize);
|
||||||
|
|
||||||
|
//- спрашиваю пользователя
|
||||||
|
WriteLine(Localization.MessageSplitAsk, fileInfo.FileName,
|
||||||
|
new FileSizeConverter(Localization.FileSizeStrings).Convert(fileInfo.FileSize),
|
||||||
|
BitConverter.ToString(fileInfo.FileHash).Replace("-", "").ToLowerInvariant(),
|
||||||
|
fileInfo.SplitCount);
|
||||||
|
|
||||||
|
//- получаю ответ
|
||||||
|
string? userInput = ReadLine();
|
||||||
|
|
||||||
|
//- проверяю согласие
|
||||||
|
if (userInput == null || userInput.ToLower() != "y")
|
||||||
|
//-- и прерываю, если не получил
|
||||||
|
return FsExitCode.ecUserAborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Выполняю разбиение
|
||||||
|
return FileSplitterClass.SplitFile(fileName, targetDir, partSize, options.AsReadOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Выполняю сборку
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="infoFileName">Файл информации о разбиении</param>
|
||||||
|
/// <param name="targetFileName">Целевой файл</param>
|
||||||
|
/// <param name="silent">Тихий режим (без запросов)</param>
|
||||||
|
/// <param name="options">Параметры сборки</param>
|
||||||
|
/// <returns>Код возврата</returns>
|
||||||
|
public static FsExitCode DoJoin (string infoFileName, string targetFileName, bool silent, List<FileJoinOptions> options)
|
||||||
|
{
|
||||||
|
//Функция прогресса
|
||||||
|
#pragma warning disable CS8622
|
||||||
|
FileSplitterClass.OnProgress += OnProgress;
|
||||||
|
#pragma warning restore CS8622
|
||||||
|
|
||||||
|
//Если не выбран тихий режим
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
//- спрашиваю пользователя
|
||||||
|
WriteLine(Localization.MessageJoinAsk, targetFileName);
|
||||||
|
|
||||||
|
//- получаю ответ
|
||||||
|
string? userInput = ReadLine();
|
||||||
|
|
||||||
|
//- проверяю согласие
|
||||||
|
if (userInput == null || userInput.ToLower() != "y")
|
||||||
|
//-- и прерываю, если не получил
|
||||||
|
return FsExitCode.ecUserAborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Выполняю объединение
|
||||||
|
return FileSplitterClass.JoinFile(infoFileName, targetFileName, options.AsReadOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FsExitCode DoInteractive ()
|
||||||
|
{
|
||||||
|
//Пользовательский ввод
|
||||||
|
string userInput;
|
||||||
|
|
||||||
|
//Цикл получения информации
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//Вывожу приветственный запрос на выбор операции
|
||||||
|
WriteLine(Localization.InteractiveStartAsk);
|
||||||
|
|
||||||
|
//Получаю ответ
|
||||||
|
userInput = ReadLine() ?? string.Empty;
|
||||||
|
|
||||||
|
//Обработано ли решение
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
//Обрабатываем выбор пользователя
|
||||||
|
switch (userInput.ToLower())
|
||||||
|
{
|
||||||
|
//Если пользователь выбрал разбиение
|
||||||
|
case "s":
|
||||||
|
{
|
||||||
|
//- то запускаем разбиение
|
||||||
|
FsExitCode splitExitCode = DoSplitInteractive();
|
||||||
|
|
||||||
|
//- вывожу сообщение
|
||||||
|
WriteLine(Localization.InteractiveOperationFinish, Localization.ExitCodeNames.First(eCode => eCode.Item1 == splitExitCode).Item2);
|
||||||
|
|
||||||
|
//- указываем на перехват
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Если пользователь указал на выход
|
||||||
|
case "e":
|
||||||
|
//- то указываем на перехват
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Если решение не обработано
|
||||||
|
if (!handled)
|
||||||
|
//- то вывожу сообщение
|
||||||
|
WriteLine(Localization.InteractiveWrongInput);
|
||||||
|
} while (userInput.ToLower() != "e");
|
||||||
|
|
||||||
|
//Закрываю интерактивную операцию
|
||||||
|
return FsExitCode.ecAllDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Интерактивное разбиение файла
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see cref="FsExitCode"/></returns>
|
||||||
|
public static FsExitCode DoSplitInteractive ()
|
||||||
|
{
|
||||||
|
//Пользовательский ввод
|
||||||
|
string userInput;
|
||||||
|
|
||||||
|
//Обработан ли ввод
|
||||||
|
bool isHandled = false;
|
||||||
|
|
||||||
|
/* Имя файла */
|
||||||
|
//Выбор имени файла
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//Запрос имени файла
|
||||||
|
WriteLine(Localization.InteractiveSplitFileNameAsk);
|
||||||
|
|
||||||
|
//Считываю имя файла
|
||||||
|
userInput = ReadLine() ?? string.Empty;
|
||||||
|
|
||||||
|
//Если файл не существует
|
||||||
|
if (!File.Exists(userInput))
|
||||||
|
{
|
||||||
|
//- то запрашиваю действие
|
||||||
|
WriteLine(Localization.InteractiveFileNameNotExist);
|
||||||
|
|
||||||
|
//- считываю ответ
|
||||||
|
userInput = ReadLine() ?? string.Empty;
|
||||||
|
|
||||||
|
//- если выбрано не повторять
|
||||||
|
if (userInput.ToLower() != "y")
|
||||||
|
//-- то прерываю операцию
|
||||||
|
return FsExitCode.ecUserAborted;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//В противном случае, считаю ввод корректным
|
||||||
|
isHandled = true;
|
||||||
|
}
|
||||||
|
} while (!isHandled);
|
||||||
|
|
||||||
|
//Ввожу переменную с именем файла
|
||||||
|
string fileName = userInput;
|
||||||
|
|
||||||
|
//Вывожу информацию о выборе файла
|
||||||
|
WriteLine(Localization.InteractiveSplitFileNameResult, fileName);
|
||||||
|
|
||||||
|
/* Целевая папка */
|
||||||
|
|
||||||
|
//Выбираю целевую папку
|
||||||
|
WriteLine(Localization.InteractiveSplitTargetDirAsk);
|
||||||
|
|
||||||
|
//Считываю данные
|
||||||
|
userInput = ReadLine() ?? string.Empty;
|
||||||
|
|
||||||
|
//Если вместо папки пустое место
|
||||||
|
if (string.IsNullOrWhiteSpace(userInput))
|
||||||
|
//- то задаю папку имени файла
|
||||||
|
userInput = Path.GetDirectoryName(fileName) ?? string.Empty;
|
||||||
|
|
||||||
|
//Ввожу переменную целевой папки
|
||||||
|
string targetDir = LikeDelphi.IncludeTrailingBackslash(userInput);
|
||||||
|
|
||||||
|
//Вывожу информацию о выборе целевой папки
|
||||||
|
WriteLine(Localization.InteractiveSplitTargetDirResult, targetDir);
|
||||||
|
|
||||||
|
/* Размер части */
|
||||||
|
//Ввожу переменную размера части
|
||||||
|
long partSize;
|
||||||
|
|
||||||
|
//Создаю конвертер
|
||||||
|
FileSizeConverter converter = new(Localization.FileSizeStrings, 1);
|
||||||
|
|
||||||
|
//Устанавливаю перехват в false
|
||||||
|
isHandled = false;
|
||||||
|
|
||||||
|
//Выбор размер части
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//Получаю размер исходного файла
|
||||||
|
long fileSize = FileExtension.FileSize(fileName);
|
||||||
|
|
||||||
|
//Запрос размера части
|
||||||
|
WriteLine(Localization.InteractiveSplitPartSizeAsk);
|
||||||
|
|
||||||
|
//Считываю размер части
|
||||||
|
userInput = ReadLine() ?? fileSize.ToString();
|
||||||
|
|
||||||
|
//Задаю размер части
|
||||||
|
partSize = TypeConverter.StrToInt64(userInput, fileSize);
|
||||||
|
|
||||||
|
//Запрашиваю согласие на размер части
|
||||||
|
WriteLine(Localization.InteractiveSplitPartSizeAsk2, converter.Convert(partSize));
|
||||||
|
|
||||||
|
//Считываю ответ
|
||||||
|
userInput = ReadLine() ?? string.Empty;
|
||||||
|
|
||||||
|
//Если согласен, то выхожу из цикла
|
||||||
|
if (userInput.ToLower() == "y")
|
||||||
|
isHandled = true;
|
||||||
|
} while (!isHandled);
|
||||||
|
|
||||||
|
//Вывожу информацию о размере части
|
||||||
|
WriteLine(Localization.InteractiveSplitPartSizeResult, converter.Convert(partSize));
|
||||||
|
|
||||||
|
/* Опции разбиения */
|
||||||
|
//Ввожу переменную опций разбиения
|
||||||
|
List<FileSplitOptions> options = new();
|
||||||
|
|
||||||
|
//Запрос опций разбиения
|
||||||
|
WriteLine(Localization.InteractiveSplitOptionsAsk);
|
||||||
|
|
||||||
|
//Считываю опции разбиения
|
||||||
|
userInput = (ReadLine() ?? string.Empty).ToLower().Trim();
|
||||||
|
|
||||||
|
//Инициализирую список параметров
|
||||||
|
ConsoleParamsParser @params = new(userInput.Split(' '));
|
||||||
|
|
||||||
|
//Проверяю параметры разбиения
|
||||||
|
//- отключена ли проверка хэша
|
||||||
|
if (@params.HasParam("/NoCheckHash"))
|
||||||
|
options.Add(FileSplitOptions.fsoNoCheckHash);
|
||||||
|
//- нужно ли удалять исходный файл
|
||||||
|
if (@params.HasParam("/DeleteSource"))
|
||||||
|
options.Add(FileSplitOptions.fsoDeleteSourceFileAfterSplit);
|
||||||
|
//- нужно ли шифровать файл информации
|
||||||
|
if (@params.HasParam("/EncryptInfoFile"))
|
||||||
|
options.Add(FileSplitOptions.fsoEncryptInfoFile);
|
||||||
|
|
||||||
|
//Вывожу информацию о выборе параметров
|
||||||
|
WriteLine(Localization.InteractiveSplitOptionsResult, userInput);
|
||||||
|
|
||||||
|
/* Выполнение разбиения */
|
||||||
|
return DoSplit(fileName, targetDir, partSize, false, options);
|
||||||
|
}
|
||||||
|
}
|
@ -27,4 +27,8 @@
|
|||||||
<ProjectReference Include="..\FileSplitterShared\FileSplitterShared.csproj" />
|
<ProjectReference Include="..\FileSplitterShared\FileSplitterShared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Classes\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using anbs_cp.Classes;
|
using anbs_cp.Classes;
|
||||||
|
|
||||||
|
using FileSplitter.Console.Classes;
|
||||||
using FileSplitter.Shared.Classes;
|
using FileSplitter.Shared.Classes;
|
||||||
using FileSplitter.Shared.Enums;
|
using FileSplitter.Shared.Enums;
|
||||||
|
|
||||||
@ -18,23 +19,24 @@ Console.WriteLine(
|
|||||||
$"\t{string.Format(Localization.AppCopyrights, DateTime.Now.Year == 2023 ? "2023" : $"2023 - {DateTime.Now.Year}")}");
|
$"\t{string.Format(Localization.AppCopyrights, DateTime.Now.Year == 2023 ? "2023" : $"2023 - {DateTime.Now.Year}")}");
|
||||||
Console.WriteLine("********************************************************************************");
|
Console.WriteLine("********************************************************************************");
|
||||||
|
|
||||||
//Прерываем, если нет параметров
|
|
||||||
if (!consoleParser.HasParam("split") && !consoleParser.HasParam("join"))
|
|
||||||
{
|
|
||||||
Console.WriteLine(Localization.MessageNoParameters);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Разделение файлов
|
|
||||||
|
//Разделение файлов по параметрам
|
||||||
if (consoleParser.HasParam("split"))
|
if (consoleParser.HasParam("split"))
|
||||||
FileSplit(consoleParser);
|
return FileSplit4Params(consoleParser);
|
||||||
|
|
||||||
//Соединение файлов
|
//Соединение файлов по параметрам
|
||||||
if (consoleParser.HasParam("join"))
|
if (consoleParser.HasParam("join"))
|
||||||
FileJoin(consoleParser);
|
return FileJoin4Params(consoleParser);
|
||||||
|
|
||||||
//Функция разделения файлов
|
//Если нет параметров, то запускаем интерактивный режим
|
||||||
static void FileSplit (ConsoleParamsParser @params)
|
return StartInteractive();
|
||||||
|
|
||||||
|
//Запуск интерактивного режима
|
||||||
|
static int StartInteractive () => (int) Executor.DoInteractive();
|
||||||
|
|
||||||
|
//Функция разделения файлов для параметров
|
||||||
|
static int FileSplit4Params (ConsoleParamsParser @params)
|
||||||
{
|
{
|
||||||
//Проверяю наличие параметров
|
//Проверяю наличие параметров
|
||||||
if (!@params.HasParam("-fn") || !@params.HasParam("-td") || !@params.HasParam("-ps"))
|
if (!@params.HasParam("-fn") || !@params.HasParam("-td") || !@params.HasParam("-ps"))
|
||||||
@ -43,7 +45,7 @@ static void FileSplit (ConsoleParamsParser @params)
|
|||||||
Console.WriteLine(Localization.MessageNoParametersForSplit);
|
Console.WriteLine(Localization.MessageNoParametersForSplit);
|
||||||
|
|
||||||
//- прерываю
|
//- прерываю
|
||||||
return;
|
return (int)FsExitCode.ecInvalidParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Получаю параметры
|
//Получаю параметры
|
||||||
@ -67,17 +69,15 @@ static void FileSplit (ConsoleParamsParser @params)
|
|||||||
if (@params.HasParam("/EncryptInfoFile"))
|
if (@params.HasParam("/EncryptInfoFile"))
|
||||||
options.Add(FileSplitOptions.fsoEncryptInfoFile);
|
options.Add(FileSplitOptions.fsoEncryptInfoFile);
|
||||||
|
|
||||||
//Функция прогресса
|
//Получаю параметры консоли
|
||||||
#pragma warning disable CS8622
|
bool silent = @params.HasParam("--silent");
|
||||||
FileSplitterClass.OnProgress += OnProgress;
|
|
||||||
#pragma warning restore CS8622
|
|
||||||
|
|
||||||
//Выполняю разбиение
|
//Выполняю разбиение
|
||||||
FileSplitterClass.SplitFile(fileName, targetDir, partSize, options.AsReadOnly());
|
return (int)Executor.DoSplit(fileName, targetDir, partSize, silent, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Функция объединения
|
//Функция объединения для параметров
|
||||||
static void FileJoin (ConsoleParamsParser @params)
|
static int FileJoin4Params (ConsoleParamsParser @params)
|
||||||
{
|
{
|
||||||
//Проверяю наличие параметров
|
//Проверяю наличие параметров
|
||||||
if (!@params.HasParam("-ifn") || !@params.HasParam("-tfn"))
|
if (!@params.HasParam("-ifn") || !@params.HasParam("-tfn"))
|
||||||
@ -86,7 +86,7 @@ static void FileJoin (ConsoleParamsParser @params)
|
|||||||
Console.WriteLine(Localization.MessageNoParametersForSplit);
|
Console.WriteLine(Localization.MessageNoParametersForSplit);
|
||||||
|
|
||||||
//- прерываю
|
//- прерываю
|
||||||
return;
|
return (int)FsExitCode.ecInvalidParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Получаю параметры
|
//Получаю параметры
|
||||||
@ -110,19 +110,12 @@ static void FileJoin (ConsoleParamsParser @params)
|
|||||||
//- нужно ли отключить проверку версии файла информации
|
//- нужно ли отключить проверку версии файла информации
|
||||||
if (@params.HasParam("/IgnoreVersion"))
|
if (@params.HasParam("/IgnoreVersion"))
|
||||||
options.Add(FileJoinOptions.fjoIgnoreSupportedScriptVersion);
|
options.Add(FileJoinOptions.fjoIgnoreSupportedScriptVersion);
|
||||||
|
//- нужно ли отключить проверку объединённого файла на корректность
|
||||||
|
if (@params.HasParam("/SkipCheck"))
|
||||||
|
options.Add(FileJoinOptions.fjoSkipCheckJoinedFile);
|
||||||
|
|
||||||
//Функция прогресса
|
//Получаю параметры консоли
|
||||||
#pragma warning disable CS8622
|
bool silent = @params.HasParam("--silent");
|
||||||
FileSplitterClass.OnProgress += OnProgress;
|
|
||||||
#pragma warning restore CS8622
|
|
||||||
|
|
||||||
//Выполняю объединение
|
return (int)Executor.DoJoin(infoFileName, targetFileName, silent, options);
|
||||||
FileSplitterClass.JoinFile(infoFileName, targetFileName, options.AsReadOnly());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Функция вывода прогресса
|
|
||||||
static void OnProgress (object sender, FileSplitterOnProgress args)
|
|
||||||
{
|
|
||||||
//Вывод сообщения в консоль
|
|
||||||
Console.WriteLine(args.Message);
|
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0411_0430_0431_0430_0435_0432/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0411_0430_0431_0430_0435_0432/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043E_0431_044A_0435_0434_0438_043D_0451_043D_043D_043E_0433_043E/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043E_0431_044A_0435_0434_0438_043D_0451_043D_043D_044B_0439/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_0435/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_0435/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_043C_0438/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_043C_0438/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_0445/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0430_0437_0434_0435_043B_0451_043D_043D_044B_0445/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -22,6 +22,31 @@ public static class FileSplitterClass
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static event EventHandler<FileSplitterOnProgress>? OnProgress;
|
public static event EventHandler<FileSplitterOnProgress>? OnProgress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получает информацию о файле, который готовится к разбиению
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">Имя файла</param>
|
||||||
|
/// <param name="partSize">Размер части</param>
|
||||||
|
/// <returns>Информация о файле (<see cref="TargetFileInfo"/>)</returns>
|
||||||
|
public static TargetFileInfo GetSplitFileInfo (string fileName, long partSize)
|
||||||
|
{
|
||||||
|
//Получаю размер текущего файла
|
||||||
|
long fileSize = FileExtension.FileSize(fileName);
|
||||||
|
|
||||||
|
//Получаю информацию о целевом файле
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
//Имя файла
|
||||||
|
FileName = Path.GetFileName(fileName),
|
||||||
|
//Размер файла
|
||||||
|
FileSize = fileSize,
|
||||||
|
//md5-сумма файла (хэш)
|
||||||
|
FileHash = new FileHash(fileName).Hash,
|
||||||
|
//Количество кусков
|
||||||
|
SplitCount = (long)Math.Round(fileSize / (decimal)partSize, MidpointRounding.ToPositiveInfinity)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Разделение файла на части
|
/// Разделение файла на части
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -29,7 +54,8 @@ public static class FileSplitterClass
|
|||||||
/// <param name="targetDir">Папка, в которую нужно сохранить файлы</param>
|
/// <param name="targetDir">Папка, в которую нужно сохранить файлы</param>
|
||||||
/// <param name="partSize">Размер части в байтах</param>
|
/// <param name="partSize">Размер части в байтах</param>
|
||||||
/// <param name="options">Параметры разбиения</param>
|
/// <param name="options">Параметры разбиения</param>
|
||||||
public static void SplitFile (string fileName, string targetDir, long partSize, ReadOnlyCollection<FileSplitOptions> options)
|
/// <returns>Код возврата</returns>
|
||||||
|
public static FsExitCode SplitFile (string fileName, string targetDir, long partSize, ReadOnlyCollection<FileSplitOptions> options)
|
||||||
{
|
{
|
||||||
//Задаю обработчик для распаковки
|
//Задаю обработчик для распаковки
|
||||||
EventHandler<FileSplitterOnProgress>? onProgressEvent = OnProgress;
|
EventHandler<FileSplitterOnProgress>? onProgressEvent = OnProgress;
|
||||||
@ -57,14 +83,7 @@ public static class FileSplitterClass
|
|||||||
long fileSize = FileExtension.FileSize(fileName);
|
long fileSize = FileExtension.FileSize(fileName);
|
||||||
|
|
||||||
//Получаю информацию о целевом файле
|
//Получаю информацию о целевом файле
|
||||||
splitInfo.TargetFile = new()
|
splitInfo.TargetFile = GetSplitFileInfo(fileName, partSize);
|
||||||
{
|
|
||||||
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));
|
BinaryReader fileReader = new(File.Open(fileName, FileMode.Open));
|
||||||
@ -126,9 +145,14 @@ public static class FileSplitterClass
|
|||||||
if (!options.Contains(FileSplitOptions.fsoNoCheckHash))
|
if (!options.Contains(FileSplitOptions.fsoNoCheckHash))
|
||||||
//- и если не прошли проверку
|
//- и если не прошли проверку
|
||||||
if (!CheckHash(targetDir, Path.GetFileName(fileName), splitInfo.SplitFiles))
|
if (!CheckHash(targetDir, Path.GetFileName(fileName), splitInfo.SplitFiles))
|
||||||
|
{
|
||||||
//- то удаляем файлы разбиения
|
//- то удаляем файлы разбиения
|
||||||
DeleteSplitFiles(Path.GetFileName(fileName), targetDir, splitInfo.TargetFile.SplitCount);
|
DeleteSplitFiles(Path.GetFileName(fileName), targetDir, splitInfo.TargetFile.SplitCount);
|
||||||
|
|
||||||
|
//- возвращаю ошибку хэша
|
||||||
|
return FsExitCode.ecSplitFileHashError;
|
||||||
|
}
|
||||||
|
|
||||||
//Имя файла информации о разбиении
|
//Имя файла информации о разбиении
|
||||||
string reportFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{Path.GetFileName(fileName)}.fsi";
|
string reportFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{Path.GetFileName(fileName)}.fsi";
|
||||||
|
|
||||||
@ -150,6 +174,9 @@ public static class FileSplitterClass
|
|||||||
if (options.Contains(FileSplitOptions.fsoDeleteSourceFileAfterSplit))
|
if (options.Contains(FileSplitOptions.fsoDeleteSourceFileAfterSplit))
|
||||||
//- то удаляю его
|
//- то удаляю его
|
||||||
File.Delete(fileName);
|
File.Delete(fileName);
|
||||||
|
|
||||||
|
//Закрываю консоль с успехом
|
||||||
|
return FsExitCode.ecAllDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -158,7 +185,8 @@ public static class FileSplitterClass
|
|||||||
/// <param name="infoFileName">Имя файла с информацией о разделении</param>
|
/// <param name="infoFileName">Имя файла с информацией о разделении</param>
|
||||||
/// <param name="targetFileName">Целевой файл</param>
|
/// <param name="targetFileName">Целевой файл</param>
|
||||||
/// <param name="options">Параметры объединения</param>
|
/// <param name="options">Параметры объединения</param>
|
||||||
public static void JoinFile (string infoFileName, string targetFileName, ReadOnlyCollection<FileJoinOptions> options)
|
/// <returns>Код возврата</returns>
|
||||||
|
public static FsExitCode JoinFile (string infoFileName, string targetFileName, ReadOnlyCollection<FileJoinOptions> options)
|
||||||
{
|
{
|
||||||
//Задаю обработчик для распаковки
|
//Задаю обработчик для распаковки
|
||||||
EventHandler<FileSplitterOnProgress>? onProgressEvent = OnProgress;
|
EventHandler<FileSplitterOnProgress>? onProgressEvent = OnProgress;
|
||||||
@ -195,7 +223,7 @@ public static class FileSplitterClass
|
|||||||
{
|
{
|
||||||
onProgressEvent?.Invoke(null,
|
onProgressEvent?.Invoke(null,
|
||||||
new(0, 0, Localization.MessageJoinUnknownFile));
|
new(0, 0, Localization.MessageJoinUnknownFile));
|
||||||
Environment.Exit(2);
|
return FsExitCode.ecUnknownInfoFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Проверяю версию
|
//Проверяю версию
|
||||||
@ -207,7 +235,7 @@ public static class FileSplitterClass
|
|||||||
new(0, 0, string.Format(Localization.MessageJoinUnsupportedFile, splitInfo.FileSplitterVersion)));
|
new(0, 0, string.Format(Localization.MessageJoinUnsupportedFile, splitInfo.FileSplitterVersion)));
|
||||||
|
|
||||||
//Прерываю
|
//Прерываю
|
||||||
return;
|
return FsExitCode.ecInfoVersionUnsupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Получаю папку с разделёнными файлами
|
//Получаю папку с разделёнными файлами
|
||||||
@ -221,7 +249,7 @@ public static class FileSplitterClass
|
|||||||
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinHashError));
|
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinHashError));
|
||||||
|
|
||||||
//Прерываю
|
//Прерываю
|
||||||
return;
|
return FsExitCode.ecSplitFileHashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Открываю файл
|
//Открываю файл
|
||||||
@ -260,12 +288,36 @@ public static class FileSplitterClass
|
|||||||
//Освобождаю память
|
//Освобождаю память
|
||||||
fileWriter.Dispose();
|
fileWriter.Dispose();
|
||||||
|
|
||||||
|
//Проверяю объединённый файл
|
||||||
|
//- получаю хэш
|
||||||
|
IStructuralEquatable fileHashEq = new FileHash(targetFileName).Hash;
|
||||||
|
|
||||||
|
//- проверяю
|
||||||
|
if (
|
||||||
|
//-- проверка не отключена опцией
|
||||||
|
!options.Contains(FileJoinOptions.fjoSkipCheckJoinedFile) &&
|
||||||
|
//-- совпадает ли размер
|
||||||
|
FileExtension.FileSize(targetFileName) != splitInfo.TargetFile.FileSize &&
|
||||||
|
//-- совпадает ли хэш
|
||||||
|
!fileHashEq.Equals(splitInfo.TargetFile.FileHash, StructuralComparisons.StructuralEqualityComparer)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//Вывожу сообщение
|
||||||
|
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinCheckError));
|
||||||
|
|
||||||
|
//Прерываю
|
||||||
|
return FsExitCode.ecTargetFileCheckError;
|
||||||
|
}
|
||||||
|
|
||||||
//Вывожу сообщение
|
//Вывожу сообщение
|
||||||
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinComplete));
|
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinComplete));
|
||||||
|
|
||||||
//Удаляю разделённые файлы
|
//Удаляю разделённые файлы
|
||||||
if (options.Contains(FileJoinOptions.fjoDeleteSourceFilesAfterJoin))
|
if (options.Contains(FileJoinOptions.fjoDeleteSourceFilesAfterJoin))
|
||||||
DeleteSplitFiles(splitInfo.TargetFile.FileName, sourceDir, splitInfo.TargetFile.SplitCount);
|
DeleteSplitFiles(splitInfo.TargetFile.FileName, sourceDir, splitInfo.TargetFile.SplitCount);
|
||||||
|
|
||||||
|
//Возвращаю успех
|
||||||
|
return FsExitCode.ecAllDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace FileSplitter.Shared.Classes;
|
using FileSplitter.Shared.Enums;
|
||||||
|
|
||||||
|
namespace FileSplitter.Shared.Classes;
|
||||||
|
|
||||||
public static class Localization
|
public static class Localization
|
||||||
{
|
{
|
||||||
@ -8,24 +10,53 @@ public static class Localization
|
|||||||
public const string AppCopyrights = "Авторские права (C) {0}, Александр Бабаев.";
|
public const string AppCopyrights = "Авторские права (C) {0}, Александр Бабаев.";
|
||||||
|
|
||||||
//Сообщения
|
//Сообщения
|
||||||
public const string MessageNoParameters =
|
|
||||||
"Нет параметров. Информацию о работе с программой смотрите в файле \"Help\\Russian\\Console.html\"";
|
|
||||||
public const string MessageNoParametersForSplit =
|
public const string MessageNoParametersForSplit =
|
||||||
"Не заданы параметры разбиения. Информацию о работе с программой смотрите в файле \"Help\\Russian\\Console.html\"";
|
"Не заданы параметры разбиения. Информацию о работе с программой смотрите в файле \"Help\\Russian\\Console.html\"";
|
||||||
|
public const string MessageSplitAsk =
|
||||||
|
"Информация о разбиваемом файле:\n***{0}\n***Размер: {1}\n***Хэш файла: {2}\n***Предполагается разбиение на {3} части(-ей)\nВы хотите начать разбиение? [Y|y - да, Любая другая буква/слово/выражение - нет]";
|
||||||
public const string MessageStartSplit = "Запущено разбиение файла {0} на части размером {1} и сохранением их в директории {2}.";
|
public const string MessageStartSplit = "Запущено разбиение файла {0} на части размером {1} и сохранением их в директории {2}.";
|
||||||
public const string MessageSplitFilePart = "Идёт обработка части {0} из {1}...";
|
public const string MessageSplitFilePart = "Идёт обработка части {0} из {1}...";
|
||||||
public const string MessageSplitComplete = "Разбиение файла {0} завершено!";
|
public const string MessageSplitComplete = "Разбиение файла {0} завершено!";
|
||||||
public const string MessageHashCheckStart = "Начинаю проверку хэша разбиения";
|
public const string MessageHashCheckStart = "Начинаю проверку хэша разбиения";
|
||||||
public const string MessageHashCheckFail = "К сожалению, файл \"{0}\" не прошёл проверку хэша!";
|
public const string MessageHashCheckFail = "К сожалению, файл \"{0}\" не прошёл проверку хэша!";
|
||||||
public const string MessageHashCheckComplete = "Проверка хэша завершена!";
|
public const string MessageHashCheckComplete = "Проверка хэша завершена!";
|
||||||
|
public const string MessageJoinAsk = "Вы хотите начать сборку файла {0}? [Y|y - да, любая другая буква/слово/выражение - нет]";
|
||||||
public const string MessageStartJoin = "Запущено объединение файлов, заданных файлом информации {0}, в файл {1}.";
|
public const string MessageStartJoin = "Запущено объединение файлов, заданных файлом информации {0}, в файл {1}.";
|
||||||
public const string MessageJoinUnsupportedFile = "К сожалению, версия файла информации {0} не поддерживается!";
|
public const string MessageJoinUnsupportedFile = "К сожалению, версия файла информации {0} не поддерживается!";
|
||||||
public const string MessageJoinUnknownFile = "Не могу прочитать файл информации! Возможно он зашифрован?";
|
public const string MessageJoinUnknownFile = "Не могу прочитать файл информации! Возможно он зашифрован?";
|
||||||
public const string MessageJoinHashError = "К сожалению, разделённые файлы не прошли проверку. Возможно они повреждены?";
|
public const string MessageJoinHashError = "К сожалению, разделённые файлы не прошли проверку. Возможно они повреждены?";
|
||||||
|
public const string MessageJoinCheckError =
|
||||||
|
"К сожалению, объединённый файл не прошли проверку корректности объединения. Возможно были какие-либо ошибки?";
|
||||||
public const string MessageJoinFilePart = "Идёт обработка части {0} из {1}...";
|
public const string MessageJoinFilePart = "Идёт обработка части {0} из {1}...";
|
||||||
public const string MessageJoinComplete = "Объединение файла {0} завершено!";
|
public const string MessageJoinComplete = "Объединение файла {0} завершено!";
|
||||||
|
|
||||||
|
//Сообщения интерактивного режима
|
||||||
|
public const string InteractiveStartAsk = "Выберете одно из действий:\n* S|s - разбиение\n* J|j - объединение\n* E|e - выход\nВаш выбор:";
|
||||||
|
public const string InteractiveWrongInput = "Выбрано неизвестное действие!";
|
||||||
|
public const string InteractiveOperationFinish = "Операция завершена с кодом: {0}";
|
||||||
|
public const string InteractiveSplitFileNameAsk = "Введите имя разбиваемого файла (или перетащите его сюда):";
|
||||||
|
public const string InteractiveFileNameNotExist = "Файл не существует! Повторить ввод файла? [Y|y - для повтора, любая другая буква - прерывание операции]";
|
||||||
|
public const string InteractiveSplitFileNameResult = "Для разбиения выбран файл: {0}";
|
||||||
|
public const string InteractiveSplitTargetDirAsk = "Выберете папку, куда следует сохранить части файла (или оставьте пустым, чтобы использовать папку разбиваемого файла):";
|
||||||
|
public const string InteractiveSplitTargetDirResult = "Файлы разбиения будут сохранены в папке: {0}";
|
||||||
|
public const string InteractiveSplitPartSizeAsk = "Введите размер части (в байтах):";
|
||||||
|
public const string InteractiveSplitPartSizeAsk2 = "Вы выбрали размер части {0}. Всё правильно? [Y|y - да, продолжить, любая другая буква - нет, повторить ввод]";
|
||||||
|
public const string InteractiveSplitPartSizeResult = "Выбран размер части: {0}";
|
||||||
|
public const string InteractiveSplitOptionsAsk = "Введите дополнительные параметры разбиения (разделитель - пробел):";
|
||||||
|
public const string InteractiveSplitOptionsResult = "Выбраны дополнительные параметры: [{0}]";
|
||||||
|
|
||||||
//Константы размеров
|
//Константы размеров
|
||||||
public static readonly string[] FileSizeStrings = { "байт", "Кб", "Мб", "Гб", "Тб" };
|
public static readonly string[] FileSizeStrings = { "байт", "Кб", "Мб", "Гб", "Тб" };
|
||||||
|
|
||||||
|
//Переводы кодов возврата
|
||||||
|
public static readonly List<(FsExitCode, string)> ExitCodeNames = new()
|
||||||
|
{
|
||||||
|
(FsExitCode.ecAllDone, "Успешно завершено"),
|
||||||
|
(FsExitCode.ecInvalidParameters, "Неверные параметры"),
|
||||||
|
(FsExitCode.ecUserAborted, "Прервано пользователем"),
|
||||||
|
(FsExitCode.ecUnknownInfoFile, "Неизвестный файл информации о разбиении"),
|
||||||
|
(FsExitCode.ecInfoVersionUnsupported, "Версия файла информации о разбиении не поддерживается"),
|
||||||
|
(FsExitCode.ecSplitFileHashError, "Ошибка проверки хэш-суммы разделённых файлов"),
|
||||||
|
(FsExitCode.ecTargetFileCheckError, "Ошибка проверки целостности собираемого файла")
|
||||||
|
};
|
||||||
}
|
}
|
@ -23,5 +23,10 @@ public enum FileJoinOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Игнорировать не поддерживаемую версию файла информации
|
/// Игнорировать не поддерживаемую версию файла информации
|
||||||
/// </summary>
|
/// </summary>
|
||||||
fjoIgnoreSupportedScriptVersion = 3
|
fjoIgnoreSupportedScriptVersion = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пропустить проверку объединённого файла на корректность
|
||||||
|
/// </summary>
|
||||||
|
fjoSkipCheckJoinedFile = 4
|
||||||
}
|
}
|
42
FileSplitterShared/Enums/FsExitCode.cs
Normal file
42
FileSplitterShared/Enums/FsExitCode.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
namespace FileSplitter.Shared.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Коды возврата
|
||||||
|
/// </summary>
|
||||||
|
public enum FsExitCode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Успешно завершено
|
||||||
|
/// </summary>
|
||||||
|
ecAllDone = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Неверные параметры
|
||||||
|
/// </summary>
|
||||||
|
ecInvalidParameters = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Прервано пользователем
|
||||||
|
/// </summary>
|
||||||
|
ecUserAborted = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Неизвестный файл информации о разбиении
|
||||||
|
/// </summary>
|
||||||
|
ecUnknownInfoFile = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Версия файла информации о разбиении не поддерживается
|
||||||
|
/// </summary>
|
||||||
|
ecInfoVersionUnsupported = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ошибка проверки хэш-суммы разделённых файлов
|
||||||
|
/// </summary>
|
||||||
|
ecSplitFileHashError = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ошибка проверки целостности собираемого файла
|
||||||
|
/// </summary>
|
||||||
|
ecTargetFileCheckError = 6
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user