J'essaie de créer un flux Zip à la volée avec des données de tableau d'octets et de le faire télécharger via mon action MVC.
Mais le fichier téléchargé donne toujours l'erreur corrompue suivante lorsqu'il est ouvert dans Windows.
Et cette erreur quand j'essaye d'extraire de 7z
Mais notez que les fichiers extraits du 7z ne sont pas corrompus.
J'utilise ZipArchive
et voici mon code.
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");
}
Qu'est-ce que je fais de mal ici.
Toute aide serait très appréciée car je lutte avec cela pendant une journée entière.
Merci d'avance
Déplacez zipStream.ToArray()
en dehors de zipArchive
à l'aide de.
La raison de votre problème est que le flux est mis en mémoire tampon. Il y a plusieurs façons de le gérer:
AutoFlush
du flux sur true
..Flush()
sur le flux.Ou, puisque c'est MemoryStream
et que vous utilisez .ToArray()
, vous pouvez simplement autoriser le flux à être fermé/supprimé en premier (ce que nous avons fait en le déplaçant en dehors de using
).
Je Dispose ZipArchive Et erreur résolue
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();
}
J'avais également des problèmes avec cela et j'ai trouvé que mon problème n'était pas la génération de l'archive elle-même mais plutôt la façon dont je traitais ma demande GET dans AngularJS.
Ce message m'a aidé: comment télécharger un fichier Zip en utilisant angulaire
La clé ajoutait responseType: 'arraybuffer'
à mon appel $ http.
factory.serverConfigExportZIP = function () {
return $http({
url: dataServiceBase + 'serverConfigExport',
method: "GET",
responseType: 'arraybuffer'
})
};