20230415
This commit is contained in:
@@ -22,6 +22,31 @@ public static class FileSplitterClass
|
||||
/// </summary>
|
||||
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>
|
||||
@@ -29,7 +54,8 @@ public static class FileSplitterClass
|
||||
/// <param name="targetDir">Папка, в которую нужно сохранить файлы</param>
|
||||
/// <param name="partSize">Размер части в байтах</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;
|
||||
@@ -57,14 +83,7 @@ public static class FileSplitterClass
|
||||
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)
|
||||
};
|
||||
splitInfo.TargetFile = GetSplitFileInfo(fileName, partSize);
|
||||
|
||||
//Открываю файл
|
||||
BinaryReader fileReader = new(File.Open(fileName, FileMode.Open));
|
||||
@@ -126,9 +145,14 @@ public static class FileSplitterClass
|
||||
if (!options.Contains(FileSplitOptions.fsoNoCheckHash))
|
||||
//- и если не прошли проверку
|
||||
if (!CheckHash(targetDir, Path.GetFileName(fileName), splitInfo.SplitFiles))
|
||||
{
|
||||
//- то удаляем файлы разбиения
|
||||
DeleteSplitFiles(Path.GetFileName(fileName), targetDir, splitInfo.TargetFile.SplitCount);
|
||||
|
||||
//- возвращаю ошибку хэша
|
||||
return FsExitCode.ecSplitFileHashError;
|
||||
}
|
||||
|
||||
//Имя файла информации о разбиении
|
||||
string reportFileName = $"{LikeDelphi.IncludeTrailingBackslash(targetDir)}{Path.GetFileName(fileName)}.fsi";
|
||||
|
||||
@@ -150,6 +174,9 @@ public static class FileSplitterClass
|
||||
if (options.Contains(FileSplitOptions.fsoDeleteSourceFileAfterSplit))
|
||||
//- то удаляю его
|
||||
File.Delete(fileName);
|
||||
|
||||
//Закрываю консоль с успехом
|
||||
return FsExitCode.ecAllDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -158,7 +185,8 @@ public static class FileSplitterClass
|
||||
/// <param name="infoFileName">Имя файла с информацией о разделении</param>
|
||||
/// <param name="targetFileName">Целевой файл</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;
|
||||
@@ -195,7 +223,7 @@ public static class FileSplitterClass
|
||||
{
|
||||
onProgressEvent?.Invoke(null,
|
||||
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)));
|
||||
|
||||
//Прерываю
|
||||
return;
|
||||
return FsExitCode.ecInfoVersionUnsupported;
|
||||
}
|
||||
|
||||
//Получаю папку с разделёнными файлами
|
||||
@@ -221,7 +249,7 @@ public static class FileSplitterClass
|
||||
onProgressEvent?.Invoke(null, new(0, 0, Localization.MessageJoinHashError));
|
||||
|
||||
//Прерываю
|
||||
return;
|
||||
return FsExitCode.ecSplitFileHashError;
|
||||
}
|
||||
|
||||
//Открываю файл
|
||||
@@ -260,12 +288,36 @@ public static class FileSplitterClass
|
||||
//Освобождаю память
|
||||
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));
|
||||
|
||||
//Удаляю разделённые файлы
|
||||
if (options.Contains(FileJoinOptions.fjoDeleteSourceFilesAfterJoin))
|
||||
DeleteSplitFiles(splitInfo.TargetFile.FileName, sourceDir, splitInfo.TargetFile.SplitCount);
|
||||
|
||||
//Возвращаю успех
|
||||
return FsExitCode.ecAllDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -1,4 +1,6 @@
|
||||
namespace FileSplitter.Shared.Classes;
|
||||
using FileSplitter.Shared.Enums;
|
||||
|
||||
namespace FileSplitter.Shared.Classes;
|
||||
|
||||
public static class Localization
|
||||
{
|
||||
@@ -8,24 +10,53 @@ public static class Localization
|
||||
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 MessageSplitAsk =
|
||||
"Информация о разбиваемом файле:\n***{0}\n***Размер: {1}\n***Хэш файла: {2}\n***Предполагается разбиение на {3} части(-ей)\nВы хотите начать разбиение? [Y|y - да, Любая другая буква/слово/выражение - нет]";
|
||||
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 MessageJoinAsk = "Вы хотите начать сборку файла {0}? [Y|y - да, любая другая буква/слово/выражение - нет]";
|
||||
public const string MessageStartJoin = "Запущено объединение файлов, заданных файлом информации {0}, в файл {1}.";
|
||||
public const string MessageJoinUnsupportedFile = "К сожалению, версия файла информации {0} не поддерживается!";
|
||||
public const string MessageJoinUnknownFile = "Не могу прочитать файл информации! Возможно он зашифрован?";
|
||||
public const string MessageJoinHashError = "К сожалению, разделённые файлы не прошли проверку. Возможно они повреждены?";
|
||||
public const string MessageJoinCheckError =
|
||||
"К сожалению, объединённый файл не прошли проверку корректности объединения. Возможно были какие-либо ошибки?";
|
||||
public const string MessageJoinFilePart = "Идёт обработка части {0} из {1}...";
|
||||
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 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>
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user