Создать zip файл из байта []
Я пытаюсь создать Zip файл в .NET 4.5 (System.IO.Compression) из серии байт-массивов. Например, из API, который я использую, я заканчиваю с List<Attachment>
, и каждый Attachment
имеет свойство Body
, которое является byte[]
. Как я могу перебирать этот список и создавать zip файл, содержащий каждое вложение?
Сейчас у меня создается впечатление, что мне придется записывать каждое вложение на диск и создавать из него zip файл.
//This is great if I had the files on disk
ZipFile.CreateFromDirectory(startPath, zipPath);
//How can I create it from a series of byte arrays?
Ответы
Ответ 1
Немного поиграв и почитав, я смог в этом разобраться. Вот как вы можете создать zip файл (архив) с несколькими файлами без записи временных данных на диск:
using (var compressedFileStream = new MemoryStream())
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, false)) {
foreach (var caseAttachmentModel in caseAttachmentModels) {
//Create a zip entry for each attachment
var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body))
using (var zipEntryStream = zipEntry.Open()) {
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
return new FileContentResult(compressedFileStream.ToArray(), "application/zip") { FileDownloadName = "Filename.zip" };
}
Ответ 2
Это вариация большого принятого ответа, опубликованного OP. Однако это для WebForms вместо MVC. Я работаю с предположением, что caseAttachmentModel.Body является байтом []
По сути, все одно и то же, за исключением дополнительного метода, который отправляет zip в качестве ответа.
using (var compressedFileStream = new MemoryStream()) {
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false)) {
foreach (var caseAttachmentModel in caseAttachmentModels) {
//Create a zip entry for each attachment
var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body)) {
using (var zipEntryStream = zipEntry.Open()) {
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
}
sendOutZIP(compressedFileStream.ToArray(), "FileName.zip");
}
private void sendOutZIP(byte[] zippedFiles, string filename)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/x-compressed";
Response.Charset = string.Empty;
Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
Response.BinaryWrite(zippedFiles);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
}
Я также хотел бы отметить, что советы, данные @Levi Fuller по ссылкам в принятом ответе, находятся на месте!
Ответ 3
GZipStream и DeflateStream кажутся, что они позволят вам использовать пар/байтовые массивы для решения вашей проблемы, но, возможно, не с форматом файла сжатия, который может использоваться большинством пользователей. (т.е. ваш файл будет иметь расширение .gz). Если этот файл используется только внутри, это может быть все в порядке.
Я не знаю, как вы можете сделать ZIP с помощью библиотек Microsoft, но я помню эту библиотеку, поддерживающую то, что вам может пригодиться:
http://sevenzipsharp.codeplex.com/
Он лицензируется под LGPL.