ZipArchive 给出数据损坏错误的意外结束
ZipArchive gives Unexpected end of data corrupted error
我正在尝试使用一些字节数组数据动态创建一个 zip 流,并通过我的 MVC 操作下载它。
但是下载的文件在windows中打开时总是出现以下损坏的错误。
当我尝试从 7z 提取时出现此错误
但请注意,从 7z 中提取的文件没有损坏。
我正在使用 ZipArchive
,下面是我的代码。
private byte[] GetZippedPods(IEnumerable<POD> pods, long consignmentID)
{
using (var zipStream = new MemoryStream())
{
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
int index = 1;
foreach (var pod in pods)
{
var zipEntry = zipArchive.CreateEntry($"POD{consignmentID}{index++}.png", CompressionLevel.NoCompression);
using (var originalFileStream = new MemoryStream(pod.ByteData))
{
using (var zipEntryStream = zipEntry.Open())
{
originalFileStream.CopyTo(zipEntryStream);
}
}
}
return zipStream.ToArray();
}
}
}
public ActionResult DownloadPOD(long consignmentID)
{
var pods = _consignmentService.GetPODs(consignmentID);
var fileBytes = GetZippedPods(pods, consignmentID);
return File(fileBytes, MediaTypeNames.Application.Octet, $"PODS{consignmentID}.zip");
}
我哪里做错了。
任何帮助将不胜感激,因为我为此苦苦挣扎了一整天。
提前致谢
将 zipStream.ToArray()
移到 zipArchive
之外。
你的问题的原因是流被缓冲了。有几种方法可以解决它:
- 您可以将流的
AutoFlush
属性 设置为 true
。
- 您可以在直播中手动调用
.Flush()
。
或者,因为它是 MemoryStream
而您正在使用 .ToArray()
,您可以简单地让流先 Closed/Disposed(我们通过将它移到using
).
我也遇到了这个问题,我发现我的问题不是存档本身的生成,而是我如何在 AngularJS 中处理我的 GET 请求。
这个post帮助了我:
关键是将 responseType: 'arraybuffer'
添加到我的 $http 调用中。
factory.serverConfigExportZIP = function () {
return $http({
url: dataServiceBase + 'serverConfigExport',
method: "GET",
responseType: 'arraybuffer'
})
};
我处理了 ZipArchive 并解决了错误
public static byte[] GetZipFile(Dictionary<string, List<FileInformation>> allFileInformations)
{
MemoryStream compressedFileStream = new MemoryStream();
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true))
{
foreach (var fInformation in allFileInformations)
{
var files = allFileInformations.Where(x => x.Key == fInformation.Key).SelectMany(x => x.Value).ToList();
for (var i = 0; i < files.Count; i++)
{
ZipArchiveEntry zipEntry = zipArchive.CreateEntry(fInformation.Key + "/" + files[i].FileName);
var caseAttachmentModel = Encoding.UTF8.GetBytes(files[i].Content);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(caseAttachmentModel))
using (var zipEntryStream = zipEntry.Open())
{
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
//i added this line
zipArchive.Dispose();
return compressedFileStream.ToArray();
}
}
public void SaveZipFile(){
var zipFileArray = Global.GetZipFile(allFileInformations);
var zipFile = new MemoryStream(zipFileArray);
FileStream fs = new FileStream(path + "\111.zip",
FileMode.Create,FileAccess.Write);
zipFile.CopyTo(fs);
zipFile.Flush();
fs.Close();
zipFile.Close();
}
您可以删除 "using" 并使用 Dispose 和 Close 方法
对我有用
...
zip.Dispose();
zipStream.Close();
return zipStream.ToArray();
我知道这是一个 C# 问题,但对于托管 C++,请在完成 ZipArchive^ 后删除它以修复错误。
ZipArchive^ zar = ZipFile::Open(starget, ZipArchiveMode::Create);
ZipFileExtensions::CreateEntryFromFile(zar, sfile1, "file.txt");
ZipFileExtensions::CreateEntryFromFile(zar, sfile2, "file2.txt");
delete zar;
我正在尝试使用一些字节数组数据动态创建一个 zip 流,并通过我的 MVC 操作下载它。
但是下载的文件在windows中打开时总是出现以下损坏的错误。
当我尝试从 7z 提取时出现此错误
但请注意,从 7z 中提取的文件没有损坏。
我正在使用 ZipArchive
,下面是我的代码。
private byte[] GetZippedPods(IEnumerable<POD> pods, long consignmentID)
{
using (var zipStream = new MemoryStream())
{
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
int index = 1;
foreach (var pod in pods)
{
var zipEntry = zipArchive.CreateEntry($"POD{consignmentID}{index++}.png", CompressionLevel.NoCompression);
using (var originalFileStream = new MemoryStream(pod.ByteData))
{
using (var zipEntryStream = zipEntry.Open())
{
originalFileStream.CopyTo(zipEntryStream);
}
}
}
return zipStream.ToArray();
}
}
}
public ActionResult DownloadPOD(long consignmentID)
{
var pods = _consignmentService.GetPODs(consignmentID);
var fileBytes = GetZippedPods(pods, consignmentID);
return File(fileBytes, MediaTypeNames.Application.Octet, $"PODS{consignmentID}.zip");
}
我哪里做错了。
任何帮助将不胜感激,因为我为此苦苦挣扎了一整天。
提前致谢
将 zipStream.ToArray()
移到 zipArchive
之外。
你的问题的原因是流被缓冲了。有几种方法可以解决它:
- 您可以将流的
AutoFlush
属性 设置为true
。 - 您可以在直播中手动调用
.Flush()
。
或者,因为它是 MemoryStream
而您正在使用 .ToArray()
,您可以简单地让流先 Closed/Disposed(我们通过将它移到using
).
我也遇到了这个问题,我发现我的问题不是存档本身的生成,而是我如何在 AngularJS 中处理我的 GET 请求。
这个post帮助了我:
关键是将 responseType: 'arraybuffer'
添加到我的 $http 调用中。
factory.serverConfigExportZIP = function () {
return $http({
url: dataServiceBase + 'serverConfigExport',
method: "GET",
responseType: 'arraybuffer'
})
};
我处理了 ZipArchive 并解决了错误
public static byte[] GetZipFile(Dictionary<string, List<FileInformation>> allFileInformations)
{
MemoryStream compressedFileStream = new MemoryStream();
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true))
{
foreach (var fInformation in allFileInformations)
{
var files = allFileInformations.Where(x => x.Key == fInformation.Key).SelectMany(x => x.Value).ToList();
for (var i = 0; i < files.Count; i++)
{
ZipArchiveEntry zipEntry = zipArchive.CreateEntry(fInformation.Key + "/" + files[i].FileName);
var caseAttachmentModel = Encoding.UTF8.GetBytes(files[i].Content);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(caseAttachmentModel))
using (var zipEntryStream = zipEntry.Open())
{
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
//i added this line
zipArchive.Dispose();
return compressedFileStream.ToArray();
}
}
public void SaveZipFile(){
var zipFileArray = Global.GetZipFile(allFileInformations);
var zipFile = new MemoryStream(zipFileArray);
FileStream fs = new FileStream(path + "\111.zip",
FileMode.Create,FileAccess.Write);
zipFile.CopyTo(fs);
zipFile.Flush();
fs.Close();
zipFile.Close();
}
您可以删除 "using" 并使用 Dispose 和 Close 方法 对我有用
...
zip.Dispose();
zipStream.Close();
return zipStream.ToArray();
我知道这是一个 C# 问题,但对于托管 C++,请在完成 ZipArchive^ 后删除它以修复错误。
ZipArchive^ zar = ZipFile::Open(starget, ZipArchiveMode::Create);
ZipFileExtensions::CreateEntryFromFile(zar, sfile1, "file.txt");
ZipFileExtensions::CreateEntryFromFile(zar, sfile2, "file2.txt");
delete zar;