私はいくつかのバイト配列データを使用してその場でZipストリームを作成し、MVCアクションを介してダウンロードできるようにしています。
ただし、ダウンロードしたファイルをWindowsで開くと、常に次の破損したエラーが発生します。
そして、私が7zからxtractしようとすると、このエラー
ただし、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");
}
ここで何が悪いのでしょうか。
私は一日中これに苦労しているので、どんな助けも高く評価されます。
前もって感謝します
zipArchive
の外でzipStream.ToArray()
を使用して移動します。
問題の理由は、ストリームがバッファリングされていることです。それを扱うにはいくつかの方法があります:
AutoFlush
プロパティをtrue
に設定できます。.Flush()
を呼び出すことができます。または、MemoryStream
であり、.ToArray()
を使用しているため、ストリームを最初に閉じる/破棄することを許可できます(これは、using
)。
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();
}
これにも問題があり、問題はアーカイブ自体の生成ではなく、AngularJSでのGETリクエストの処理方法にあることがわかりました。
この投稿は私を助けました: angularを使用してZipファイルをダウンロードする方法
キーはresponseType: 'arraybuffer'
私の$ http呼び出しに。
factory.serverConfigExportZIP = function () {
return $http({
url: dataServiceBase + 'serverConfigExport',
method: "GET",
responseType: 'arraybuffer'
})
};