Создание zip в C# с System.IO.Packaging
Я пытаюсь динамически создать zip-файл на сервере, который содержит фотографии из онлайн-сервисов. Но когда я пытаюсь открыть файл, WinRar говорит, что файл неизвестного формата или поврежден.
это код:
MemoryStream stream = new MemoryStream();
Package package = ZipPackage.Open(stream, FileMode.Create, FileAccess.ReadWrite);
foreach (Order o in orders)
{
o.GetImages();
Parallel.ForEach(o.Images, (Dictionary<string, object> image) =>
{
string imageId = (string)image["ID"];
int orderId = (int)image["OrderId"];
string fileName = (string)image["FileName"];
string url = (string)image["URL"];
if (string.IsNullOrEmpty(fileName))
{
System.Net.WebClient wc = new System.Net.WebClient();
byte[] data = wc.DownloadData(url);
MemoryStream ms = new MemoryStream(data);
ms.Write(data, 0, data.Length);
string ext;
switch(wc.ResponseHeaders["Content-Type"])
{
case "image/jpeg":
case "image/jpg":
ext = "jpg";
break;
case "image/png":
ext = "png";
break;
case "image/gif":
ext = "gif";
break;
default :
ext = "un";
break;
}
Uri uri = new Uri("/" + orderId.ToString() + "/" + imageId + "." + ext, UriKind.Relative);
var part = package.CreatePart(uri, wc.ResponseHeaders["Content-Type"], CompressionOption.NotCompressed);
var pstream = part.GetStream(FileMode.Open, FileAccess.ReadWrite);
pstream.Write(data, 0, data.Length);
var rel = package.CreateRelationship(part.Uri, TargetMode.Internal, "http://example.com/AlbumImage");
}
});
}
package.Flush();
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, Convert.ToInt32(stream.Length));
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=Orders.zip");
Response.AddHeader("Content-Length", stream.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(fileBytes);
Response.End();
2 ответа
Это все о пакете Uris. Мы также были избиты ими. Вот рабочий пример для хранения двух файлов в формате zip. Код только что скопирован из нашего проекта с удалением некоторых личных данных.
var dataFilePath = Path.GetFileName(dataFileName);
var dataFileUri = PackUriHelper.CreatePartUri(new Uri(dataFilePath, UriKind.Relative));
// Create the Package
using (var package = Package.Open(filePath, FileMode.Create))
{
// Add the diagram view part to the Package
var pkgPart = package.CreatePart(dataFileUri, MediaTypeNames.Application.Octet);
var pkgStream = pkgPart.GetStream();
// Copy the data to the model view part
// diagramFileName Encoding.Default.GetBytes(text)
using (var modelStream = new FileStream(dataFileName, FileMode.Open, FileAccess.Read))
{
const int bufSize = 0x1000;
var buf = new byte[bufSize];
int bytesRead;
while ((bytesRead = modelStream.Read(buf, 0, bufSize)) > 0)
{
pkgStream.Write(buf, 0, bytesRead);
}
}
// Add a context Part to the Package
var pkgPartContext = package.CreatePart(ctxUri, MediaTypeNames.Application.Octet);
var ctxPkgStream = pkgPartContext.GetStream();
// Copy the data to the context part
using (var ctxStream = new FileStream(ctxFileName, FileMode.Open, FileAccess.Read))
{
const int bufSize = 0x1000;
var buf = new byte[bufSize];
int bytesRead;
while ((bytesRead = ctxStream.Read(buf, 0, bufSize)) > 0)
{
ctxPkgStream.Write(buf, 0, bytesRead);
}
}
}
// remove tmp files
File.Delete(ctxFileName);
File.Delete(dataFileName);
Я знаю, что этот вопрос немного устарел, но у меня была похожая проблема. я использовал
stream.Seek(0, SeekOrigin.Begin);
и это сработало