Генерировать Zip файл из azure blob файлов

У меня есть несколько файлов, хранящихся в моем хранилище azure blob. IWant взять эти файлы и создать zip файл и сохранить в новой папке. Затем вернуть путь к zip файлу. Установите разрешение на размещение zip файла, чтобы мои пользователи могли загрузить zip файл на свои локальные компьютеры, нажав на ссылку

 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/AppList/isjirleq/mydocs1.doc
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/tempo/xyz/mymusic.mp3
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/general/video/myVideo.wmv
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/photo/photo1.png

Я хочу, чтобы иметь возможность прокручивать эти файлы и объединять их все вместе, чтобы создать новый zip файл

(https://mystorage.blob.core.windows.net/myzippedfiles/allmyFiles.zip) и верните путь к zip файлу

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

Как я могу это сделать. Мне нужен пример кода для этого

Ответ 1

Мы решили эту проблему (частично), запустив файлы непосредственно в выходной поток, используя потоки blob. Это позволяет избежать проблемы загрузки zipping, а затем отправки и позволяет избежать задержки, когда это происходит (мы использовали ICSharpZipLib, ссылка). Но это все равно означает маршрутизацию потока через веб-сервер:

  public void ZipFilesToResponse(HttpResponseBase response, IEnumerable<Asset> files, string zipFileName)
    {
        using (var zipOutputStream = new ZipOutputStream(response.OutputStream))
        {
            zipOutputStream.SetLevel(0); // 0 - store only to 9 - means best compression
            response.BufferOutput = false;
            response.AddHeader("Content-Disposition", "attachment; filename=" + zipFileName);
            response.ContentType = "application/octet-stream";

            foreach (var file in files)
            {
                var entry = new ZipEntry(file.FilenameSlug())
                {
                    DateTime = DateTime.Now,
                    Size = file.Filesize
                };
                zipOutputStream.PutNextEntry(entry);
                storageService.ReadToStream(file, zipOutputStream);
                response.Flush();
                if (!response.IsClientConnected)
                {
                   break;
                }
            }
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        response.End();
    }

Служба хранения просто делает это:

public void ReadToStream(IFileIdentifier file, Stream stream, StorageType storageType = StorageType.Stored, ITenant overrideTenant = null)
    {
        var reference = GetBlobReference(file, storageType, overrideTenant);
        reference.DownloadToStream(stream);
    }
private CloudBlockBlob GetBlobReference(IFileIdentifier file, StorageType storageType = StorageType.Stored, ITenant overrideTenant = null)
        {
            var filepath = GetFilePath(file, storageType);
            var container = GetTenantContainer(overrideTenant);
            return container.GetBlockBlobReference(filepath);
        }

Ответ 2

Поскольку хранилище blob является "просто" хранилищем объектов, вам нужно будет загружать их где-нибудь (это может быть роль веб-/работника или ваш локальный компьютер), zip их, а затем reupload zip файл. Это единственный способ сделать это, насколько мне известно.

Ответ 3

Я не думаю, что вы можете избежать их загрузки, локально скопировать их и загрузить.

Утилиты сжатия работают только с локальными ресурсами. Сам Azure Storage не имеет понятия/способности иметь возможность сжимать некоторые файлы самостоятельно

Ответ 4

Я был бы на 99% уверен, что для любой zip-библиотеки, которую вы используете, потребуются локальные ресурсы/локальные файлы, чтобы создать zip файл.

Посмотрите на локальное хранилище Azure для рабочих ролей.

http://vkreynin.wordpress.com/2010/01/10/learning-azure-local-storage-with-me/

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

например.

//Создаем раздел локального хранилища в вашей конфигурации.

<WebRole name="...">
 <LocalResources>
   <LocalStorage name="myLocalStorage" sizeInMB="50"/>
 </LocalResources>
</WebRole>

//Затем сохраните ваши файлы в локальном хранилище

CloudBlobContainer container = blobClient.GetContainerReference("myfiles");
CloudBlob blob = container.GetBlobReference("2b5f8ea6-3dc2-4b77-abfe-4da832e02556/AppList/isjirleq/mydocs1.doc");

LocalResource myStorage = RoleEnvironment.GetLocalResource("myLocalStorage");
string filePath = Path.Combine(myStorage.RootPath, "mydocs1.doc");
blob.DownloadToFile(filePath);

После того, как вы сохранили все ваши файлы, сохраненные в LocalStorage, используйте ZipLibrary для объединения всех путей к файлу вместе

Ответ 5

Я думаю, вы можете использовать webjob или роль рабочего для этого. Когда вы получаете запрос пользователя, нажмите этот запрос в очередь, а затем верните идентификатор задания пользователю. Webjob или рабочая роль извлекают запрос из очереди и загружают эти файлы и зашифровывают их, а затем загружают zip файл обратно в Storage blob. Код передней стороны может использовать опрос ajax roll с идентификатором задания, чтобы получить реальный URL-адрес загрузки, когда это будет сделано.

Ответ 6

Не думайте, что azure предоставляет какие-либо функции из коробки для zipping. Если вам нужно избегать поворота времени, возможно, использование роли рабочего фона - хорошая идея, которая выберет ваши файлы из определенной очереди. Запишите их и сохраните url для вы где-то вроде sql db.Я делал схожие вещи, общавшись с db, поэтому вы можете быть уверены, что он будет работать очень быстро, не понимая, что его на самом деле не происходит на лицевой стороне.