Архивация данных на языке C#
В этом примере вы сможете с лёгкостью архивировать ваши данные файлов на версии .NetFramework от v4.0 - v4.5 и выше.
Нажмите: скачать всё необходимое для вашей работы! (В этом архиве лежат все нужные классы которые вы можете использовать для работы с архивацией)
Начнём работу со стандартными архиваторами которые установлены на машине пользователя, а это 7-Zip , WinRAR
Для работы мне потребовалась некоторая документация:
Сначала находим где установлены эти архиваторы, будем использовать реестр для нахождения, воспользуемся данным кодом ниже:
[Внимание] В данном коде используется версия C# 8.0
Класс для нахождения стандартных архиваторов на компьютере через реестр.
namespace Archiver
{
using Microsoft.Win32; public static class RegZipPath
{
/// <summary>
/// Метод для поиска установленного WinRAR архиватора в системе через реестр
/// </summary>
/// <returns>Путь к <b>.exe</b> архиватору</returns>
public static string FindWinRar()
{
string result = string.Empty;
try
{
const string REGPATH = @"WinRAR\Shell\Open\Command";
using RegistryKey Root = Registry.ClassesRoot.OpenSubKey(REGPATH);
string winrarPath = (Root?.GetValue(""))?.ToString();
winrarPath = winrarPath.Substring(1, winrarPath.Length - 7);
result = winrarPath;
}
catch { }
return result;
} /// <summary>
/// Метод для поиска установленного 7-Zip архиватора в системе через реестр
/// </summary>
/// <returns>Путь к <b>.exe</b> архиватору</returns>
public static string FindWinZip()
{
string result = string.Empty;
try
{
const string REGPATH = @"Software\7-Zip";
using RegistryKey zip = Registry.CurrentUser.OpenSubKey(REGPATH);
result = string.Concat((zip?.GetValue("Path"))?.ToString(), "7z.exe");
}
catch { }
return result;
}
}
}Эти два метода из класса RegZipPath.cs позволять находить путь к .exe-шнику нужного архиватора, если тот установлен в системе.
Теперь перейдём в другой класс который будет отвечать за саму архивацию папки.
Класс в котором используются 2-а метода для архивации папки с максимальным сжатием и разархивации архива.
Для 7-Zip используется данный метод PackZip
Расшифровка аргументов для Архивации папки:
t - тип. Определяет тип архива, который вы хотите создать: -t7z Формат: 7Z -tgzip Формат: GZIP -tzip Формат: ZIP -tbzip2 Формат: BZIP2 -ttar Формат: TAR -tiso Формат: ISO -tudf Формат: UDF
-r( Обрабатывать вложенные папки ){outputzip}.zip( Имя выходного архива ){datapath}(Путь к папке, которую нужно архивировать)-mx=9( Уровень сжатия архива, 1 - Fast | 9 Ultra )
public static class ArchCmd
{
/// <summary>
/// Метод для архивации папки с ультра сжатием.
/// </summary>
/// <param name="zipshell">Путь к архиватору</param>
/// <param name="datapath">Путь к папке которую нужно архивировать</param>
/// <param name="outputzip">Выходной путь, куда сохранять с новым именем архива</param>
public static void PackZip(string zipshell, string datapath, string outputzip)
{
if (File.Exists(zipshell) && (!string.IsNullOrWhiteSpace(datapath) || !string.IsNullOrWhiteSpace(outputzip)))
{
var pro = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = zipshell,
Arguments = $@"a -tzip -r {outputzip}.zip {datapath} -mx=9"
};
using var x = Process.Start(pro);
x.Refresh();
x.WaitForExit(); // Обязательно)
}
}Так же используется метод для распаковки UnpackZip
Расшифровка аргументов для распаковки архива:
/// <summary>
/// Метод для распаковки .zip архива
/// </summary>
/// <param name="zipshell">Путь к архиватору</param>
/// <param name="inputzip">Путь к папке которую нужно разархивировать</param>
/// <param name="outputdir">Выходной путь, куда сохранять папку</param>
public static void UnpackZip(string zipshell, string inputzip, string outputdir)
{
if (File.Exists(zipshell) && (!string.IsNullOrWhiteSpace(inputzip) || !string.IsNullOrWhiteSpace(outputdir)))
{
var pro = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = zipshell,
Arguments = quot;x {inputzip}.zip -o{outputdir}"
};
using var x = Process.Start(pro);
x.WaitForExit();
}
}/* -Примеры использования- private static readonly string CurrDir = Environment.CurrentDirectory; // Текущая директория private static readonly string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // Рабочий стол ZipDot - Имя папки которую архивируем. r3xq1 - Имя архива ( без .zip ) Для архивации: PackZip(RegZipPath.FindWinZip(), Path.Combine(CurrDir, "ZipDot"), Path.Combine(Desktop, "r3xq1")); Для распаковки: UnpackZip(RegZipPath.FindWinZip(), Path.Combine(Desktop, "r3xq1"), Path.Combine(Desktop, "r3xq1")); */
Отлично! С методом Zip архивации и разархивации мы разобрались)
Теперь сделаем тоже самое только для работы с WinRAR архиватором.
a(Добавление файлов в архив)-ep1(Исключить из пути базовую папку)-m5(Установить метод сжатия, 1 - Fast | 5 - Ultra)-
-r(Обрабатывать вложенные папки ) -y(Подразумевать ответ "Да" на все запросы - На всякий случай, чтобы не было лишних консольных окошек){outputzip}.zip(Имя выходного архива){datapath}(Путь к папке, которую нужно архивировать)
/// <summary>
/// Метод для архивации папки с ультра сжатием.
/// </summary>
/// <param name="rarshell">Путь к архиватору</param>
/// <param name="datapath">Путь к папке которую нужно архивировать</param>
/// <param name="outputzip">Выходной путь, куда сохранять с новым именем архива</param>
public static void PackRar(string rarshell, string datapath, string outputzip)
{
if (File.Exists(rarshell) && (!string.IsNullOrWhiteSpace(datapath) || !string.IsNullOrWhiteSpace(outputzip)))
{
var pro = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = rarshell,
Arguments = $@"a -ep1 -m5 -r -y {outputzip}.rar {datapath}"
};
using var x = Process.Start(pro);
x.Refresh();
x.WaitForExit();
}
}Вызов точно так же как с Zip только за место первого аргумента даём путь нахождения Winrar архиватора а не Zip.
ArchCmd.PackRar(RegZipPath.FindWinRar(), Path.Combine(CurrDir, "ZipDot"), Path.Combine(Desktop, "r3xq1"));
Теперь мы поговорим о классе Zipstorer.cs
Этот класс можно использовать в .NetFramework 4.0 за место всяких левых библиотек. Класс сможете найти в архиве, я его немного изменил чтобы было проще использовать и добавил класс ZipR3.cs через который можно вызывать необходимые методы.
public static class ZipR3
{
/* Created r3xq1 */#region Methods for adding folders to the archive | Методы для добавления папок в архив
/// <summary>
/// Method for adding folders to .Zip archive
/// <br>Метод для добавления папок в .Zip архив</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="datapath">Full path to folders to add to .zip archive<br>Полный путь к папкам для добавления в .zip архив</br></param>
/// <param name="mode">Compression method<br>Метод сжатия</br></param>
/// <param name="commentzip">Comments on the .zip archive<br>Комментарии к .zip архиву</br></param>
public static void AddMassDirectory(string zippath, string[] datapath, ZipStorer.Compression mode, string commentzip = "")
{
using var zipdir = ZipStorer.Create(zippath, commentzip);
foreach (string dir in datapath.Where(dir => Directory.Exists(dir)))
{
zipdir?.AddDirectory(mode, dir, string.Empty);
}
}
public static void AddMassDirectory(string zippath, List<string> datapath, ZipStorer.Compression mode, string commentzip = "")
{
using var zipdir = ZipStorer.Create(zippath, commentzip);
foreach (string dir in datapath.Where(dir => Directory.Exists(dir)))
{
zipdir?.AddDirectory(mode, dir, string.Empty);
}
} /// <summary>
/// <br>Метод для добавления папки в .Zip архив</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="datapath">Full path to the folder to add to the .zip archive<br>Полный путь к папке для добавления в .zip архив</br></param>
/// <param name="mode">Compression method<br>Метод сжатия</br></param>
/// <param name="commentzip">Comments on the .zip archive<br>Комментарии к .zip архиву</br></param>
public static void AddDirectory(string zippath, string datapath, ZipStorer.Compression mode, string commentzip = "")
{
using var zipdir = ZipStorer.Create(zippath, commentzip);
if (Directory.Exists(datapath))
{
zipdir?.AddDirectory(mode, datapath, string.Empty);
}
}
#endregion#region Methods for adding files to the archive | Методы для добавления файлов в архив
/// <summary>
/// Method for adding a files to a .zip archive
/// <br>Метод для добавления файлов в .zip архив</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="filepath">Full path to files to add to .zip archive<br>Полный путь к файлам для добавления в .zip архив</br></param>
/// <param name="mode">Compression method<br>Метод сжатия</br></param>
/// <param name="commentzip">Comments on the .zip archive<br>Комментарии к .zip архиву</br></param>
public static void AddMassFile(string zippath, string[] filepath, ZipStorer.Compression mode, string commentzip = "")
{
using var zip = ZipStorer.Create(zippath, commentzip);
zip.EncodeUTF8 = true;
foreach (string files in filepath.Where(files => File.Exists(files)))
{
zip?.AddFile(mode, files, Path.GetFileName(files), string.Empty);
}
}
public static void AddMassFile(string zippath, List<string> filepath, ZipStorer.Compression mode, string commentzip = "")
{
using var zip = ZipStorer.Create(zippath, commentzip);
zip.EncodeUTF8 = true;
foreach (string files in filepath.Where(files => File.Exists(files)))
{
zip?.AddFile(mode, files, Path.GetFileName(files), string.Empty);
}
} /// <summary>
/// Method for adding a file to a .zip archive
/// <br>Метод для добавления файла в .zip архив</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="filepath">Full path to the file to add to the .Zip archive<br>Полный путь к файлу для добавления в .Zip архив</br></param>
/// <param name="mode">Compression method<br>Метод сжатия</br></param>
/// <param name="commentzip">Comments on the .zip archive<br>Комментарии к .zip архиву</br></param>
public static void AddFile(string zippath, string filepath, ZipStorer.Compression mode, string commentzip = "")
{
using var zip = ZipStorer.Create(zippath, commentzip);
zip.EncodeUTF8 = true;
zip?.AddFile(mode, filepath, Path.GetFileName(filepath), string.Empty);
}#endregion
#region Methods for unpacking files from the archive | Методы для распаковки файлов из архива
/// <summary>
/// Method for unpacking a files from a .Zip archive
/// <br>Метод для распаковки файлов из .Zip архива</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="filenames">Name of files to unzip<br>Имя файлов которые нужно распаковать</br></param>
/// <param name="savepath">Path to save files<br>Путь для сохранения файлов</br></param>
public static void UnpackMassFile(string zippath, string[] filenames, string savepath)
{
using var zip = ZipStorer.Open(zippath, FileAccess.Read);
foreach (ZipStorer.ZipFileEntry entry in zip.ReadCentralDir())
{
foreach (string file in filenames.Where(file => Path.GetFileName(entry.FilenameInZip).Contains(file)))
{
zip?.ExtractFile(entry, Path.Combine(savepath, file));
}
}
} /// <summary>
/// Method for unpacking a file from a .Zip archive
/// <br>Метод для распаковки файла из .Zip архива</br>
/// </summary>
/// <param name="zippath">The path to the .zip archive folder<br>Путь к папке .zip архива</br></param>
/// <param name="filename">The name of the file you want to unzip<br>Имя файла которого нужно распаковать</br></param>
/// <param name="savepath">Path to save file<br>Путь для сохранения файла</br></param>
public static void UnpackFile(string zippath, string filename, string savepath)
{
using var zip = ZipStorer.Open(zippath, FileAccess.Read);
foreach (ZipStorer.ZipFileEntry entry in zip.ReadCentralDir().Where(entry => Path.GetFileName(entry.FilenameInZip).Contains(filename)))
{
zip?.ExtractFile(entry, Path.Combine(savepath, filename));
break;
}
}
#endregion
}Класс можете изменить под себя, как вам будет удобно.
В версии .NetFramework 4.5 имеется встроенный архиватор который вы можете использовать.
Теперь запишем метод который добавляет файлы в архив .Zip
/// <summary>
/// Метод для добавления файла в .Zip архив
/// </summary>
/// <param name="zipfile">Полный путь к .Zip архиву</param>
/// <param name="inputfile">Путь к файлу для добавления в .Zip архив</param>
/// <param name="compressionlevel">Метод сжатия</param>
public static void AddFileInZip(string zipfile, string inputfile, CompressionLevel compressionlevel)
{
try
{
using ZipArchive za = ZipFile.Open(zipfile, ZipArchiveMode.Update);
za?.CreateEntryFromFile(inputfile, Path.GetFileName(inputfile), compressionlevel);
}
catch (Exception ex) { throw new Exception("Ошибка: ", ex); }
}private static readonly string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
private static readonly string TargetFile = Path.Combine(Desktop, "11.jpg");
AddFileInZip("r3xq1.zip", TargetFile, CompressionLevel.Fastest);Можно так же использовать сторонние библиотеки для архивации, вот некоторые из них:
Примеры их использования куча, вы можете посмотреть реализации их методов на: SO - StackOverFlow CyberForum
На этом можно кончить и закончить.
Если у Вас есть желание поблагодарить меня небольшой суммой я буду только рад
BTC: 1HVjr2GmsTeRKG78rLxmX4CeQBEH8fUAhR
По всем вопросами пишите мне в:
- Telegram: @r3xq1 ( остерегайтесь фейков )
- Jabber: r3xq1@jabber.ru