Я видел много учебных руководств о том, как сжать единственный файл в c#. Но я должен смочь создать нормальный *.zip файл из больше, чем всего одного файла. Есть ли что-нибудь в.NET, которая может сделать это? Что было бы Вы предлагать (обнажающий в памяти, я нахожусь под строгими правилами и не могу пользоваться другими библиотеками),
Спасибо
Изменить: если вы используете .Net 4.5 или более позднюю версию, это встроено в структуру
Для более ранних версий или для более поздних версий control вы можете использовать функции оболочки Windows, как описано здесь, в CodeProject Джеральда Гибсона-младшего .
Я скопировал текст статьи ниже в том виде, в каком он был написан (исходная лицензия: общественное достояние )
Сжатие Zip-файлов с помощью Windows Shell API и C
Введение
Это следующая статья к тому, что я писал о распаковке Zip файлов. С помощью этого кода вы можете использовать Windows Shell API на C # для сжатия Zip-файлов и делать это без необходимости показывать окно выполнения копирования, показанное выше. Обычно, когда вы используете Shell API для сжатия Zip-файла, он отображает окно выполнения копирования, даже если вы устанавливаете параметры, чтобы Windows не показывала его.Чтобы обойти это, вы перемещаете код Shell API в отдельный исполняемый файл, а затем запускаете этот исполняемый файл с помощью класса .NET Process, обязательно устанавливая стиль окна процесса на «Скрытый».
Предпосылки
Вам когда-нибудь нужно было сжимать Zip-файлы и нужен был лучший Zip-архив, чем то, что поставляется со многими бесплатными библиотеками сжатия? Т.е. вам нужно было сжать папки и подпапки, а также файлы. Windows Zipping может сжимать не только отдельные файлы. Все, что вам нужно, - это программно заставить Windows автоматически сжимать эти Zip-файлы. Конечно, вы можете потратить 300 долларов на один из коммерческих компонентов Zip, но это трудно превзойти бесплатно, если все, что вам нужно, - это сжать иерархию папок.
Использование кода
Следующий код показывает, как использовать Windows Shell API для сжатия Zip-файла. Сначала вы создаете пустой Zip-файл. Для этого создайте правильно построенный байтовый массив, а затем сохраните этот массив как файл с расширением .zip. Как я узнал, какие байты поместить в массив? Ну, я просто использовал Windows для создания Zip-файла с одним сжатым внутри файлом. Затем я открыл Zip в Windows и удалил сжатый файл. У меня остался пустой почтовый индекс. Затем я открыл пустой Zip-файл в шестнадцатеричном редакторе (Visual Studio), посмотрел на шестнадцатеричные байтовые значения, преобразовал их в десятичные с помощью Windows Calc и скопировал эти десятичные значения в свой код байтового массива. Исходная папка указывает на папку, которую вы хотите сжать. Папка назначения указывает на только что созданный пустой Zip-файл.Этот код как есть сжимает Zip-файл, однако он также отображает окно выполнения копирования. Чтобы этот код работал, вам также нужно будет установить ссылку на библиотеку COM. В окне «Ссылки» перейдите на вкладку COM и выберите библиотеку с надписью «Microsoft Shell Controls and Automation».
//Create an empty zip file
byte[] emptyzip = new byte[]{80,75,5,6,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs.Flush();
fs.Close();
fs = null;
//Copy a folder and its contents into the newly created zip file
Shell32.ShellClass sc = new Shell32.ShellClass();
Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
Shell32.Folder DestFlder = sc.NameSpace(args[1]);
Shell32.FolderItems items = SrcFlder.Items();
DestFlder.CopyHere(items, 20);
//Ziping a file using the Windows Shell API
//creates another thread where the zipping is executed.
//This means that it is possible that this console app
//would end before the zipping thread
//starts to execute which would cause the zip to never
//occur and you will end up with just
//an empty zip file. So wait a second and give
//the zipping thread time to get started
System.Threading.Thread.Sleep(1000);
Пример решения, включенный в эту статью, показывает, как поместить этот код в консольное приложение, а затем запустить это консольное приложение для сжатия Zip-архива без отображения окна «Ход выполнения копирования».
В приведенном ниже коде показан обработчик события нажатия кнопки, который содержит код, используемый для запуска консольного приложения, чтобы во время сжатия не было пользовательского интерфейса:
private void btnUnzip_Click(object sender, System.EventArgs e)
{
//Test to see if the user entered a zip file name
if(txtZipFileName.Text.Trim() == "")
{
MessageBox.Show("You must enter what" +
" you want the name of the zip file to be");
//Change the background color to cue the user to what needs fixed
txtZipFileName.BackColor = Color.Yellow;
return;
}
else
{
//Reset the background color
txtZipFileName.BackColor = Color.White;
}
//Launch the zip.exe console app to do the actual zipping
System.Diagnostics.ProcessStartInfo i =
new System.Diagnostics.ProcessStartInfo(
AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
i.CreateNoWindow = true;
string args = "";
if(txtSource.Text.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += "\"" + txtSource.Text + "\"";
}
else
{
args += txtSource.Text;
}
string dest = txtDestination.Text;
if(dest.EndsWith(@"\") == false)
{
dest += @"\";
}
//Make sure the zip file name ends with a zip extension
if(txtZipFileName.Text.ToUpper().EndsWith(".ZIP") == false)
{
txtZipFileName.Text += ".zip";
}
dest += txtZipFileName.Text;
if(dest.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += " " + "\"" + dest + "\"";
}
else
{
args += " " + dest;
}
i.Arguments = args;
//Mark the process window as hidden so
//that the progress copy window doesn't show
i.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(i);
p.WaitForExit();
MessageBox.Show("Complete");
}
Вам следует изучить Zip Packages
. Это более структурированная версия обычных ZIP-архивов, требующая наличия некоторых метаданных в корне. Таким образом, другие инструменты ZIP могут открывать пакет, но API Sysytem.IO.Packaging не может открывать все файлы ZIP.
Для этого вы можете попробовать SharpZipLib . Это открытый исходный код, платформенно-независимый чистый код C #.
Вот несколько ресурсов, которые вы могли бы рассмотреть: Создание Zip-архивов в .NET (без внешней библиотеки, такой как SharpZipLib)
Архивирование ваших потоков с помощью System.IO.Packaging
My Рекомендация и предпочтение - использовать system.io.packacking. Это снижает ваши зависимости (только фреймворк). Сообщение Jgalloway (первая ссылка) представляет собой хороший пример добавления двух файлов в zip-файл. Да, он более подробный, но вы можете легко создать фасад (в какой-то степени это делает его AddFileToZip).
HTH
.NET имеет встроенную функциональность для сжатия файлов в пространстве имен System.IO.Compression . Используя это, вам не нужно брать дополнительную библиотеку в качестве зависимости. Эта функция доступна в .NET 2.0.
Вот способ сжатия со страницы MSDN, на которую я ссылался:
public static void Compress(FileInfo fi)
{
// Get the stream of the source file.
using (FileStream inFile = fi.OpenRead())
{
// Prevent compressing hidden and already compressed files.
if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden)
!= FileAttributes.Hidden & fi.Extension != ".gz")
{
// Create the compressed file.
using (FileStream outFile = File.Create(fi.FullName + ".gz"))
{
using (GZipStream Compress = new GZipStream(outFile,
CompressionMode.Compress))
{
// Copy the source file into the compression stream.
byte[] buffer = new byte[4096];
int numRead;
while ((numRead = inFile.Read(buffer, 0, buffer.Length)) != 0)
{
Compress.Write(buffer, 0, numRead);
}
Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
fi.Name, fi.Length.ToString(), outFile.Length.ToString());
}
}
}
}