Созданный Zip-файл недействителен после загрузки с S3 - PullRequest
1 голос
/ 12 февраля 2020

Я создаю zip-файл, который, кажется, действителен, но всегда недействителен после того, как я положил его в корзину Amazon S3. Я использую System.IO.Compression для задачи и AmazonS3Client для загрузки:

private byte[] GenerateZipFile(string tenant)
{
   byte[] zipData;

   var results = QueryAggregateTable(tenant);
   using (var memoryStream = new MemoryStream())
   using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
   {
      foreach (var item in results)
      {
          var archiveEntry = archive.CreateEntry($"{item.RowKey:D3}.json", CompressionLevel.Fastest);
          using (var entryStream = archiveEntry.Open())
          {
              var entryBytes = Encoding.UTF8.GetBytes(item.Data);
              entryStream.Write(entryBytes, 0, item.Data.Length);
          }
      }

      zipData = memoryStream.ToArray();
   }

   return zipData;
}

и

private async Task UploadToAmazon(byte[] zipData, string tenant)
{
    var bucketName = _config["egestionBucketName"];
    var configCreds = _config["egestionAwsCredentials"].Split(":");

    var awsCreds = new BasicAWSCredentials(configCreds[0], configCreds[1]);
    var awsRegion = Amazon.RegionEndpoint.GetBySystemName(_config["egestionRegionEndpointSystemName"]);

    var s3Client = new AmazonS3Client(awsCreds, awsRegion);
    using (var stream = new MemoryStream(zipData))
    {
        var putRequest = new PutObjectRequest
        {
            BucketName = bucketName,
            Key = $"{tenant}-{DateTime.UtcNow.ToString("s")}.zip",
            InputStream = stream,
            CannedACL = S3CannedACL.BucketOwnerFullControl
        };

        await s3Client.PutObjectAsync(putRequest);
    }

}

Массив байтов выглядит хорошо после возвращения из генерация и метод загрузки фактически загружают файл с правильным именем в корзину. Когда я пытаюсь загрузить файл, чтобы проверить его, я не могу открыть его с сообщением о том, что он недействителен.

У меня были некоторые проблемы с async / await, и я подозреваю, что это может быть что-то связанное, но не существует asyn c вариант для PutObject, который я могу найти. Любая помощь приветствуется.

1 Ответ

1 голос
/ 12 февраля 2020

Это не асинхронная проблема c -wait.

Байты из потока памяти собираются до того, как архив сможет записать все данные в поток. Загруженный архив является неполным и поэтому недопустимым при загрузке.

Переместить

zipData = memoryStream.ToArray();

за пределы блока архива using, чтобы любые буферизованные данные были сброшены в резервный поток при архиве утилизируется.

//...

using (var memoryStream = new MemoryStream()) {
    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) {
        foreach (var item in results) {
            var archiveEntry = archive.CreateEntry($"{item.RowKey:D3}.json", CompressionLevel.Fastest);
            using (var entryStream = archiveEntry.Open()) {
                var entryBytes = Encoding.UTF8.GetBytes(item.Data);
                entryStream.Write(entryBytes, 0, entryBytes.Length);
            }
        }
    }//Archive disposed and pushed any remaining buffered data to the stream.
    zipData = memoryStream.ToArray();
}

//...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...