Как создать программу для сжатия файлов

Пространство System.IO.Compression имен содержит следующие классы для сжатия и распаковки файлов и потоков. Эти типы также можно использовать для чтения и изменения содержимого сжатого файла:

В примерах ниже показано несколько операций для работы со сжатыми файлами. Для этих примеров требуется добавить в проект следующие пакеты NuGet:

  • System.IO.Compression;
  • System.IO.Compression.ZipFile.

Если вы используете .NET Framework, добавьте в проект ссылки на эти две библиотеки:

  • System.IO.Compression
  • System.IO.Compression.FileSystem

Пример 1: Создание и извлечение ZIP-файла

В следующем примере показано, как создавать и извлекать сжатый файл .zip с помощью класса ZipFile. В этом примере содержимое папки сжимается в новый файл.zip , а затем извлекается в новую папку.

Чтобы запустить пример, создайте папку start в папке программы и заполните ее файлами для сжатия.

Imports System.IO.Compression Module Module1 Sub Main() Dim startPath As String = «.start» Dim zipPath As String = «.result.zip» Dim extractPath As String = «.extract» ZipFile.CreateFromDirectory(startPath, zipPath) ZipFile.ExtractToDirectory(zipPath, extractPath) End Sub End Module

Пример 2: Извлечение файлов с определенными расширениями

В следующем примере выполняется перебирать содержимое существующего файла .zip и извлекать файлы с расширением .txt . Он использует класс для ZipArchive доступа к файлу.zip , а ZipArchiveEntry класс — для проверки отдельных записей. Метод расширения ExtractToFile для объекта ZipArchiveEntry доступен в классе System.IO.Compression.ZipFileExtensions.

Photoshop, сжатие файлов TIF, алгоритмом LZW

Чтобы запустить пример, поместите ZIP-файл с именем result.zip в папку программы. По запросу укажите имя папки для извлечения.

При распакуке файлов необходимо искать пути к вредоносным файлам, которые могут выйти из каталога, в который вы распакуете. Такая атака известна как обход путей. В следующем примере показано, как правильно проверить наличие вредоносных путей и безопасно извлечь файлы.

Imports System.IO Imports System.IO.Compression Module Module1 Sub Main() Dim zipPath As String = «.result.zip» Console.WriteLine(«Provide path where to extract the zip file:») Dim extractPath As String = Console.ReadLine() ‘ Normalizes the path. extractPath = Path.GetFullPath(extractPath) ‘ Ensures that the last character on the extraction path ‘ is the directory separator char. ‘ Without this, a malicious zip file could try to traverse outside of the expected ‘ extraction path. If Not extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) Then extractPath += Path.DirectorySeparatorChar End If Using archive As ZipArchive = ZipFile.OpenRead(zipPath) For Each entry As ZipArchiveEntry In archive.Entries If entry.FullName.EndsWith(«.txt», StringComparison.OrdinalIgnoreCase) Then ‘ Gets the full path to ensure that relative segments are removed.

Dim destinationPath As String = Path.GetFullPath(Path.Combine(extractPath, entry.FullName)) ‘ Ordinal match is safest, case-sensitive volumes can be mounted within volumes that ‘ are case-insensitive. If destinationPath.StartsWith(extractPath, StringComparison.Ordinal) Then entry.ExtractToFile(destinationPath) End If End If Next End Using End Sub End Module

Пример 3. Добавление файла в существующий файл .zip

В следующем примере используется класс ZipArchive для доступа к существующему ZIP-файлу и добавления в него файла. Новый файл сжимается при его добавлении в существующий файл.zip .

Python в .EXE ► КАК?


Imports System.IO Imports System.IO.Compression Module Module1 Sub Main() Using zipToOpen As FileStream = New FileStream(«c:usersexampleuserrelease.zip», FileMode.Open) Using archive As ZipArchive = New ZipArchive(zipToOpen, ZipArchiveMode.Update) Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry(«Readme.txt») Using writer As StreamWriter = New StreamWriter(readmeEntry.Open()) writer.WriteLine(«Information about this package.») writer.WriteLine(«========================») End Using End Using End Using End Sub End Module

Пример 4. Сжатие и распаковка GZ-файлов

Также вы можете использовать классы GZipStream и DeflateStream для сжатия и распаковки данных. Они применяют тот же алгоритм сжатия. Вы можете распаковать объекты GZipStream, которые записаны в GZ-файл, с помощью многих распространенных средств. В следующем примере показано, как использовать класс GZipStream для сжатия и распаковки каталога файлов.

Imports System.IO Imports System.IO.Compression Module Module1 Private directoryPath As String = «.temp» Public Sub Main() Dim directorySelected As New DirectoryInfo(directoryPath) Compress(directorySelected) For Each fileToDecompress As FileInfo In directorySelected.GetFiles(«*.gz») Decompress(fileToDecompress) Next End Sub Public Sub Compress(directorySelected As DirectoryInfo) For Each fileToCompress As FileInfo In directorySelected.GetFiles() Using originalFileStream As FileStream = fileToCompress.OpenRead() If (File.GetAttributes(fileToCompress.FullName) And FileAttributes.Hidden) <> FileAttributes.Hidden And fileToCompress.Extension <> «.gz» Then Using compressedFileStream As FileStream = File.Create(fileToCompress.FullName .gz») Using compressionStream As New GZipStream(compressedFileStream, CompressionMode.Compress) originalFileStream.CopyTo(compressionStream) End Using End Using Dim info As New FileInfo(directoryPath fileToCompress.Name .gz») Console.WriteLine($»Compressed from to bytes.») End If End Using Next End Sub Private Sub Decompress(ByVal fileToDecompress As FileInfo) Using originalFileStream As FileStream = fileToDecompress.OpenRead() Dim currentFileName As String = fileToDecompress.FullName Dim newFileName = currentFileName.Remove(currentFileName.Length — fileToDecompress.Extension.Length) Using decompressedFileStream As FileStream = File.Create(newFileName) Using decompressionStream As GZipStream = New GZipStream(originalFileStream, CompressionMode.Decompress) decompressionStream.CopyTo(decompressedFileStream) Console.WriteLine($»Decompressed: «) End Using End Using End Using End Sub End Module

Читайте также:
Прекращена работа программы singularity

См. также

  • ZipArchive
  • ZipFile
  • ZipArchiveEntry
  • DeflateStream
  • GZipStream
  • Файловый и потоковый ввод-вывод

Источник: learn.microsoft.com

Как создать программу для сжатия файлов

Кроме классов чтения-записи .NET предоставляет классы, которые позволяют сжимать файлы, а также затем восстанавливать их в исходное состояние.

Это классы ZipFile , DeflateStream и GZipStream , которые находятся в пространстве имен System.IO.Compression и представляют реализацию одного из алгоритмов сжатия Deflate или GZip.

GZipStream и DeflateStream

Для создания объекта GZipStream можно использовать один из его конструкторов:

  • GZipStream(Stream stream, CompressionLevel level) : stream представляет данные, а level задает уровень сжатия
  • GZipStream(Stream stream, CompressionMode mode) : mode указывает, будут ли данные сжиматься или, наоборот, восстанавливаться и может принимать два значения:
  • CompressionMode.Compress : данные сжимаются
  • CompressionMode.Decompress : данные восстанавливаются

Если данные сжимаются, то stream указывает на поток архивируемых данных. Если данные восстанавливаются, то stream указывает на поток, куда будут передаваться восстановленные данные.

Для управления сжатием/восстанавлением данных GZipStream предоставляет ряд методов. Основые из них:

  • void CopyTo(Stream destination) : копирует все данные в поток destination
  • Task CopyToAsync(Stream destination) : асинхронная версия метода CopyTo
  • void Flush() : очищает буфер, записывая все его данные в файл
  • Task FlushAsync() : асинхронная версия метода Flush
  • int Read(byte[] array, int offset, int count) : считывает данные из файла в массив байтов и возвращает количество успешно считанных байтов. Принимает три параметра:
  • array — массив байтов, куда будут помещены считываемые из файла данные
  • offset представляет смещение в байтах в массиве array, в который считанные байты будут помещены
  • count — максимальное число байтов, предназначенных для чтения. Если в файле находится меньшее количество байтов, то все они будут считаны.
  • array — массив байтов, куда будут помещены считываемые из файла данные
  • offset представляет смещение в байтах в массиве array, в который считанные байты будут помещены
  • count — максимальное число байтов, предназначенных для чтения. Если в файле находится меньшее количество байтов, то все они будут считаны.
  • Task ReadAsync(byte[] array, int offset, int count) : асинхронная версия метода Read
  • array — массив байтов, откуда данные будут записываться в файл
  • offset — смещение в байтах в массиве array, откуда начинается запись байтов в поток
  • count — максимальное число байтов, предназначенных для записи

Рассмотрим применение класса GZipStream на примере:

Метод CompressAsync получает название исходного файла, который надо архивировать, и название будущего сжатого файла.

Сначала создается поток для чтения из исходного файла — FileStream sourceStream . Затем создается поток для записи в сжатый файл — FileStream targetStream . Поток архивации GZipStream compressionStream инициализируется потоком targetStream и с помощью метода CopyToAsync() получает данные от потока sourceStream.

Метод DecompressAsync производит обратную операцию по восстановлению сжатого файла в исходное состояние. Он принимает в качестве параметров пути к сжатому файлу и будущему восстановленному файлу.

Здесь в начале создается поток для чтения из сжатого файла FileStream sourceStream , затем поток для записи в восстанавливаемый файл FileStream targetStream . В конце создается поток GZipStream decompressionStream , который с помощью метода CopyToAsync() копирует восстановленные данные в поток targetStream.

Чтобы указать потоку GZipStream, для чего именно он предназначен — сжатия или восстановления — ему в конструктор передается параметр CompressionMode, принимающий два значения: Compress и Decompress.

Пример консольного вывода программы:

Если бы захотели бы использовать другой класс сжатия — DeflateStream, то мы могли бы просто заменить в коде упоминания GZipStream на DeflateStream, без изменения остального кода. Их использование идентично.

В то же время при использовании этих классов есть некоторые ограничения, в частности, мы можем сжимать только один файл. Для архивации группы файлы лучше выбрать другие инструменты, например, ZipFile.

ZipFile

Статический класс ZipFile из простанства имен System.IO.Compression предоставляет дополнительные возможности для создания архивов. Он позволяет создавать архив из каталогов. Его основные методы:

  • void CreateFromDirectory(string sourceDirectoryName, string destinationFileName) : архивирует папку по пути sourceDirectoryName в файл с названием destinationFileName
  • void ExtractToDirectory(string sourceFileName, string destinationDirectoryName) : извлекает все файлы из zip-файла sourceFileName в каталог destinationDirectoryName

Оба метода имеют ряд дополнительных перегруженных версий. Рассмотрим их применение.

using System.IO.Compression; string sourceFolder = «D://test/»; // исходная папка string zipFile = «D://test.zip»; // сжатый файл string targetFolder = «D://newtest»; // папка, куда распаковывается файл ZipFile.CreateFromDirectory(sourceFolder, zipFile); Console.WriteLine($»Папка архивирована в файл «); ZipFile.ExtractToDirectory(zipFile, targetFolder); Console.WriteLine($»Файл распакован в папку «);

Читайте также:
Как перенести программу с ключом с одного компьютера на другой

В данном случае папка «D://test/» методом ZipFile.CreateFromDirectory архивируется в файл test.zip. Затем метод ZipFile.ExtractToDirectory() распаковывает данный файл в папку «D://newtest» (если такой папки нет, она создается).

Источник: metanit.com

Русские Блоги

Хаффман реализует сжатие и распаковку файлов (язык c)

Написать программу для сжатия и распаковки файлов, функции которых следующие:

Compress Может сжимать и распаковывать простые английские документы;

② Описание лучшей работы интерфейса программы.

Представляем Хаффмана:

Наиболее эффективным дискриминантным деревом является дерево Хаффмана

В компьютерной обработке данных кодирование Хаффмана использует таблицы кодирования переменной длины для кодирования исходных символов (например, буквы в файле), где таблицы кодирования переменной длины получают методом оценки вероятности появления исходных символов. Более высокие буквы используют более короткие кодировки, тогда как те, которые имеют низкую вероятность, используют более длинные кодировки, что уменьшает среднюю длину и ожидаемое значение кодированной строки, таким образом обеспечивая сжатие данных без потерь.

Например, в английском языке e имеет самую высокую вероятность появления, в то время как z имеет самую низкую вероятность появления. Когда кодирование Хаффмана используется для сжатия части английского языка, e, скорее всего, представляется одним битом, тогда как z может занимать 25 бит (не 26). При использовании общего метода представления каждая английская буква занимает один байт, то есть 8 бит. По сравнению с двумя, e использует длину 1/8 общего кодирования, а z использует более 3 раз. Если нам удастся добиться более точной оценки вероятности появления каждой буквы на английском языке, мы сможем значительно увеличить коэффициент сжатия без потерь.

Дерево Хаффмана, также известное как оптимальное двоичное дерево, представляет собой двоичное дерево с наименьшей взвешенной длиной пути. Так называемая взвешенная длина пути дерева — это вес всех листовых узлов в дереве, умноженный на длину пути до корневого узла (если корневой узел находится на уровне 0, длина пути от листового узла до корневого узла является листом). Количество узлов). Длина пути дерева представляет собой сумму длин пути от корня до каждого узла, которая записывается как WPL = (W1 * L1 + W2 * L2 + W3 * L3 + . + Wn * Ln), N весов Wi ( i = 1,2, . n) составляют двоичное дерево с N листовыми узлами, а длина пути соответствующего листового узла равна Li (i = 1,2, . n). Можно доказать, что WPL дерева Хаффмана является наименьшим.

Сжатие и распаковка файлов

Название: Фан Тяньцзуо

1 Описание процедуры

1.1структура данных

1.2 Описание функции

compress () читает содержимое файла и сжимает его, записывает сжатый контент в другой документ

uncompress () распаковывает файл и записывает распакованный контент в новый файл

1.3 Идеи и процедуры программирования

Сжатие: подсчет количества вхождений символов, сортировка узлов по количеству вхождений, построение дерева Хаффмана, настройка кодировки символов, чтение символов файла, замена символов в соответствии с установленной кодировкой и запись в файлы хранения.

Распаковка: чтение параметров файла, преобразование в двоичный код, поиск соответствующих символов в соответствии с кодом и запись в файл хранилища.

#define _CRT_SECURE_NO_WARNINGS #include #include #include struct head < int b; // символ long count; // Сколько раз этот символ появляется в файле long parent, lch, rch; //make a tree char bits[256]; //the huffuman code >; заголовок структуры заголовка [512], tmp; // дерево узлов void printfPercent(int per) < int i = 0; printf(«|»); for(i = 0; i < 10; i++) < if(i < per/10) printf(«>»); else printf(«-«); > printf («| Завершено% d %% n», за); > // Функция: compress () // Функция: прочитать содержимое файла и сжать его // Записать сжатый контент в другой документ int compress(const char *filename,const char *outputfile) < char buf[512]; unsigned char c; long i, j, m, n, f; long min1, pt1, flength; FILE *ifp, *ofp; int per = 10; ifp = fopen (filename, «rb»); // Открыть исходный файл if (ifp == NULL) < printf («Не удалось открыть файл:% s n», имя файла); return 0; // Если открытие не удалось, выведите сообщение об ошибке >ofp = fopen (outputfile, «wb»); // Открыть файл, в котором хранится информация после сжатия if (ofp == NULL) < printf («Не удалось открыть файл:% s n», выходной файл); return 0; >flength = 0; while (!feof(ifp)) < fread( header [c] .count ++; // Чтение файла и подсчет количества появлений символов flength ++; // Для записи общего количества символов в файле >flength —; header[c].count —; for (i = 0; i for (i = 0; i > > for (i = 0; i n = i; m = 2 * n — 1; for (i = n; i < m; i ++) < min1 = 999999999; for (j = 0; j < i; j ++) < if (header[j].parent != -1) continue; if (min1 >header[j].count) < pt1 = j; min1 = header[j].count; continue; >> header[i].count = header[pt1].count; header[pt1].parent = i; header[i].lch = pt1; min1 = 999999999; for (j = 0; j < i; j ++) < if (header[j].parent != -1) continue; if (min1 >header[j].count) < pt1 = j; min1 = header[j].count; continue; >> header[i].count += header[pt1].count; header[i].rch = pt1; header[pt1].parent = i; > for (i = 0; i else < j = strlen(header[i].bits); memmove(header[i].bits + 1, header[i].bits, j + 1); header[i].bits[0] = ‘1’; >> > // Далее необходимо прочитать каждый символ исходного файла и заменить символы в файле в соответствии с заданной кодировкой. fseek (ifp, 0, SEEK_SET); // Установить указатель на начало файла fseek (ofp, 8, SEEK_SET); // Чтение в 8-битных двоичных числах buf[0] = 0; f = 0; pt1 = 8; printf («Считать файл для сжатия:% s n», имя файла); printf («Текущий файл имеет:% d символ n», длина); Е ( «сжатие п»); while (!feof(ifp)) < c = fgetc(ifp); f ++; for (i = 0; i < n; i ++) < if (c == header[i].b) break; >strcat(buf, header[i].bits); j = strlen(buf); c = 0; while (j> = 8) // Когда количество оставшихся символов не менее 8 < for (i = 0; i fwrite( pt1 ++; strcpy(buf, buf + 8); j = strlen(buf); > if(100 * f/flength > per) < printfPercent(per); per += 10; >if (f == flength) break; > printfPercent(100); if (j> 0) // Когда количество оставшихся символов меньше 8 < strcat(buf, «00000000»); for (i = 0; i < 8; i ++) < if (buf[i] == ‘1’) c = (c fwrite( pt1 ++; > fseek (ofp, 0, SEEK_SET); // Запись информации о кодировании в файл хранилища fwrite( fwrite( fseek(ofp, pt1, SEEK_SET); fwrite( for (i = 0; i < n; i ++) < tmp = header[i]; fwrite( pt1++; c = strlen(header[i].bits); fwrite( pt1++; j = strlen(header[i].bits); if (j% 8! = 0) // Когда количество цифр меньше 8, выполнить заполнение нулями числа < for (f = j % 8; f < 8; f ++) strcat(header[i].bits, «0»); >while (header[i].bits[0] != 0) < c = 0; for (j = 0; j < 8; j ++) < if (header[i].bits[j] == ‘1’) c = (c strcpy(header[i].bits, header[i].bits + 8); fwrite ( // Записать полученную информацию о кодировке в файл pt1++; > header[i] = tmp; > fclose(ifp); fclose (ofp); // Закрыть файл printf («Сжатый файл:% s n», выходной файл); printf («Сжатый файл имеет:% d символ n», pt1 + 4); return 1; // Возвращаем информацию об успешном сжатии > // Функция: uncompress () // Функция: распаковать файл и записать распакованный контент в новый файл int uncompress(const char *filename,const char *outputfile) < char buf[255], bx[255]; unsigned char c; char out_filename[512]; long i, j, m, n, f, p, l; long flength; int per = 10; int len = 0; FILE *ifp, *ofp; char c_name[512] = ; ifp = fopen (filename, «rb»); // Открыть файл if (ifp == NULL) < return 0; // Если открытие не удалось, выводится сообщение об ошибке >// Читаем исходную длину файла if(outputfile) strcpy(out_filename,outputfile); else strcpy(out_filename,c_name); ofp = fopen (out_filename, «wb»); // Открыть файл if (ofp == NULL) < return 0; >fseek(ifp,0,SEEK_END); len = ftell(ifp); fseek(ifp,0,SEEK_SET); printf («Распакованный файл будет прочитан:% s n», имя файла); printf («Текущий файл имеет:% d символ n», len); Е ( «распаковка п»); fread ( // читать исходную длину файла fread( fseek(ifp, f, SEEK_SET); fread ( // Считать параметры исходного файла for (i = 0; i 0) m = p / 8 + 1; else m = p / 8; for (j = 0; j < m; j ++) < fread( f = c; _itoa(f, buf, 2); f = strlen(buf); for (l = 8; l >f; l —) < strcat (header [i] .bits, «0»); // Недостаточное количество цифр, заполнение нулями >strcat(header[i].bits, buf); > header[i].bits[p] = 0; > for (i = 0; i < n; i ++) < for (j = i + 1; j < n; j ++) < if (strlen(header[i].bits) >strlen(header[j].bits)) < tmp = header[i]; header[i] = header[j]; header[j] = tmp; >> > p = strlen(header[n-1].bits); fseek(ifp, 8, SEEK_SET); m = 0; bx[0] = 0; while (1) < while (strlen(bx) < (unsigned int)p) < fread( f = c; _itoa(f, buf, 2); f = strlen(buf); for (l = 8; l >f; l —) < strcat(bx, «0»); >strcat(bx, buf); > for (i = 0; i < n; i ++) < if (memcmp(header[i].bits, bx, header[i].count) == 0) break; >strcpy(bx, bx + header[i].count); c = header[i].b; fwrite( m ++; if(100 * m/flength > per) < printfPercent(per); per += 10; >if (m == flength) break; > printfPercent(100); fclose(ifp); fclose(ofp); printf («Файл после распаковки:% s n», out_filename); printf («Файлы после распаковки:% d символ n», длина); return 1; // Вывод сообщения об успехе > int main(int argc,const char *argv[])

Читайте также:
Программы с помощью которых пользователь организует диалог с системой www

2дисплей функции

2.1 Консольный дисплей

2.2 Эффект файла

В начале был только один файл «Test Document.txt»:

Откройте «Test Document.txt»

Размер файла «Test Document.txt»:

После запуска программы добавляются еще два файла:

Откройте сжатый двоичный файл «Test Document.txt.zip» в текстовой форме:

Атрибуты файла «Test document.txt.zip»:

Источник: russianblogs.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru