【发布时间】:2011-07-12 21:00:31
【问题描述】:
我正在尝试在服务器上动态创建包含来自在线服务的照片的 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();
【问题讨论】:
-
您是否尝试过仅使用一张图片的订单?您是否尝试过使用普通的
foreach而不是Parallel.ForEach?调用CreatePart时Package线程安全吗?看起来你要从多个线程写入流,除非CreatePart是线程安全的,否则你会得到一个损坏的流。 -
我现在只在一张图片上做,所以线程安全在这里应该不是问题
-
用普通的foreach试过了。没有变化
-
我猜它对文件的 uri 不满意。
-
我不知道 uri 应该是什么样子。 Here 已解释,据我所知,我给出了正确的 uri。但是我的英语不是很完美,所以我可能弄错了。
标签: c# .net zip system.io.packaging