Десериализовать большой двоичный объект и вывести его в другой контейнер с именем из содержимого большого двоичного объекта.

У меня есть json в лазурном двоичном объекте, который мне нужно десериализовать и получить строку. Строка - это имя большого двоичного объекта. Затем мне нужно скопировать blob-объект, который является входом для этой функции, с именем, которое я только что извлек, в контейнер для хранения.

public static void Run([BlobTrigger("output/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, TraceWriter log)
using (var sr = new StreamReader(myBlob))
using (var jsonTextReader = new JsonTextReader(sr))
{
    var transcript = (someobject)serializer.Deserialize(jsonTextReader, typeof(Transcript));
    string blobname = (someobject.Results[0].FileName).Substring(0, name.LastIndexOf('.'));

Выше приведено определение моей текущей функции и метода, который я использую для извлечения имени файла из файла json. Возможно ли это сделать с привязками ввода и вывода blob? Если да, то есть ли способ динамически выделить имя выходного большого двоичного объекта?


person Darth Veder    schedule 23.03.2018    source источник


Ответы (2)


Если вы настроите выходную привязку CloudBlockBlob, свойства Container и Name будут доступны только для чтения, что определяется атрибутом привязки [Blob]. Однако существует так называемая «императивная привязка», которая позволяет отложить привязку до времени выполнения, а example даже демонстрирует запись в произвольный контейнер больших двоичных объектов и имя файла:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;

public static async Task Run(string input, Binder binder)
{
    using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute("samples-output/path")))
    {
        writer.Write("Hello World!!");
    }
}

Для предварительно скомпилированных приложений я лично считаю, что "старомодный способ" легче читать, но я полагаю, что это вопрос предпочтений.

CloudStorageAccount storage = CloudStorageAccount.Parse(conn_str);
CloudBlobClient blobClient = storage.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference(container);
CloudBlockBlob blob =blobContainer.GetBlockBlobReference(filename);
// etc.
person McGuireV10    schedule 23.03.2018

Вы можете использовать императивную привязку для записи выходного BLOB-объекта, что-то в строках с:

public static void Run(
    [BlobTrigger("input/{name}", Connection = "AzureWebJobsStorage")] string myBlob, 
    string name, 
    Binder binder)
{
  var someobject= serializer.Deserialize<Transcript>(myBlob);
  string blobname = (someobject.Results[0].FileName).Substring(0, name.LastIndexOf('.'));

  using (var writer = binder.Bind<TextWriter>(
              new BlobAttribute($"output/{blobname}")))
  {
      writer.Write(myBlob);
  }
}

Я немного изменил вашу функцию, чтобы мой пример было легче читать.

person Mikhail Shilkov    schedule 23.03.2018
comment
проблема, с которой я столкнулся, заключается в том, что BLOB-объект загружается пустым в целевой BLOB-объект - person Darth Veder; 24.03.2018
comment
@DarthVeder Вы все еще используете Streams? Если это так, возможно, вы неправильно копируете потоки. - person Mikhail Shilkov; 24.03.2018
comment
Ага, я использую потоки. - person Darth Veder; 24.03.2018
comment
@DarthVeder Не забудьте сбросить входной поток в положение 0 перед копированием в выходной. Или выполнить рефакторинг до строк :) - person Mikhail Shilkov; 24.03.2018
comment
Я продолжал получать эту ошибку, когда пытался сбросить поток до 0: ссылка на объект не установлена ​​на экземпляр объекта - person Darth Veder; 24.03.2018
comment
можем ли мы читать из большого двоичного объекта таким же императивным способом с помощью bindasync? - person Alex Gordon; 29.05.2019