Создать большой zip-файл в ядре asp net - PullRequest
0 голосов
/ 04 марта 2019

Я создаю действие контроллера MVC, которое создает zip-файл, содержащий два файла:

  • Некоторые метаданные сериализованы из базы данных.
  • Файл соответствующего содержимого фактически хранится вBLOB-объект хранилища Azure

Пока мой контроллер работает нормально до определенного размера файла.Затем, когда содержимое Azure становится слишком большим, у меня возникает исключение из-за нехватки памяти, определенно связанное с тем, что я пишу что-то в памяти сервера, которая не бесконечна.

Так что теперь мне интересно, какой подходя должен взять?Напишите что-нибудь во временном пути на сервере или есть другие варианты?

Вот мой контроллер для справки:

public async Task<ActionResult> Download(Guid? id)
    {

        if (id == null)
        {
            return NotFound();
        }

        var cIApplication = await _context.CIApplications
            .AsNoTracking()
            .SingleOrDefaultAsync(m => m.ID == id);
        if (cIApplication == null)
        {
            return NotFound();
        }

        //Serialize metadata : this will always be small
        byte[] metaData = BinSerializer.SerializeToByteArrayAsync<CIApplication>(cIApplication);

        //GetFile from Azure blob : This can reach several GB
        //StorageManagement is an helper class to manipulate Azure storage objects
        StorageManagement storage = new StorageManagement();
        byte[] content = await storage.GetBlobToStream("application", $"{cIApplication.ID}.zip");

        //Zip It and send it
        using (MemoryStream ms = new MemoryStream())
        {
            using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
            {
                var zipArchiveEntry = archive.CreateEntry($"{cIApplication.ID}.bin", CompressionLevel.Fastest);
                using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(metaData, 0, metaData.Length);

                zipArchiveEntry = archive.CreateEntry($"{cIApplication.ID}.zip", CompressionLevel.Fastest);
                using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(content, 0, content.Length);
            }
            return File(ms.ToArray(), "application/zip", $"{cIApplication.Publisher} {cIApplication.Name} {cIApplication.Version}.zip");
        }
    }
...