Клаудблоб.DownloadToStream возвращает значение null
Я пытаюсь загрузить файл из cloudBlob через stream. Я ссылаюсь на эту статью CloudBlob
вот код для загрузки blob
public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
Stream mem = new MemoryStream();
CloudBlobClient blobclient = account.CreateCloudBlobClient();
CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);
if (blob != null)
blob.DownloadToStream(mem);
return mem;
}
и код для преобразования его в массив байтов
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
но я всегда получаю значение null. Ниже приводится содержимое файла streamed.
что в этом плохого? Пожалуйста помочь.
редактировать
установка положения в 0 внутри ReadFully
метод не допускается, поэтому я помещаю его внутрь DownloadBlobAsStream
Это должно работать так:
public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
Stream mem = new MemoryStream();
CloudBlobClient blobclient = account.CreateCloudBlobClient();
CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);
if (blob != null)
blob.DownloadToStream(mem);
mem.Position = 0;
return mem;
}
3 ответов
ваша проблема в том, что ваш указатель входного потока установлен в конец пара (см. снимок экрана, длину и положение показывают одно и то же значение), поэтому, когда вы читаете его, вы всегда получаете null. Вам нужно будет установить указатель входного потока на 0, используя поток.Позиция = 0 как показано ниже:
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
input.Position = 0; // Add this line to set the input stream position to 0
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
Как насчет использования метода OpenRead () для объекта CloudBlob?
public static string ReadFully(string blobUri, string itemUri)
{
// e.g. itemUri == "foo.txt"
// if there is a folder "bar" with foo.txt, provide instead: "bar/foo.txt"
CloudBlobContainer cloudBlobContainer = new CloudBlobContainer(new Uri(blobUri));
CloudBlob blobReference = cloudBlobContainer.GetBlobReference(itemUri);
using (var stream = blobReference.OpenRead())
{
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
Я попытался реализовать код выше, но, к моему удивлению, функция GetBlockBlobReference
не присутствовал в CloudBlobClient
а в CloudBlockBlob
.
возможно, DLL изменились со временем.
поэтому я представляю вам свою адаптацию:
public class BlobStorageHelper
{
private readonly CloudBlobClient _blobClient;
protected readonly CloudStorageAccount StorageAccount;
public string _containerName { get; set; }
public BlobStorageHelper()
{
_blobClient = base.StorageAccount.CreateCloudBlobClient();
_containerName = ConfigurationManager.AppSettings["StorageContainerName"];
StorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
}
protected Stream DownloadBlobAsStream(string blobUri)
{
CloudStorageAccount account = this.StorageAccount;
CloudBlockBlob blob = GetBlockBlobReference(account, blobUri);
Stream mem = new MemoryStream();
if (blob != null)
{
blob.DownloadToStream(mem);
}
return mem;
}
private CloudBlockBlob GetBlockBlobReference(CloudStorageAccount account, string blobUri)
{
string blobName = blobUri.Substring(blobUri.IndexOf("/" + _containerName + "/")).Replace("/" + _containerName + "/", "");
CloudBlobClient blobclient = account.CreateCloudBlobClient();
CloudBlobContainer container = _blobClient.GetContainerReference(_containerName);
container.CreateIfNotExists();
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
return blob;
}
public byte[] DownloadBlobAsByeArray(string blobUri)
{
Stream inputStream = DownloadBlobAsStream(blobUri);
byte[] buffer = new byte[16 * 1024];
inputStream.Position = 0; // Add this line to set the input stream position to 0
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}