C# CloudBlob.DownloadToStream返回null
我正在尝试通过流从cloudBlob下载一个文件。我指的是这篇文章 下面是下载blob的代码C# CloudBlob.DownloadToStream返回null,c#,azure,cloud,blob,azure-storage,C#,Azure,Cloud,Blob,Azure Storage,我正在尝试通过流从cloudBlob下载一个文件。我指的是这篇文章 下面是下载blob的代码 public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri) { Stream mem = new MemoryStream(); CloudBlobClient blobclient = account.CreateCloudBlobClient(); CloudBlockBlob
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();
}
}
但我总是得到空值。下面是流文件的内容
这有什么问题?请帮忙
编辑
不允许在ReadFully
方法中将位置设置为0,因此我将其放在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;
}
您的问题是,您的输入流指针被设置为steam的末尾(请参阅屏幕截图,长度和位置都显示相同的值),这就是为什么当您读取它时,您总是得到null。您需要使用stream.Position=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();
}
}
对CloudBlob对象使用OpenRead()方法如何
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();
}
}
}
您对此有一些误解,因为您确实可以轻松地将位置设置为0@但您需要使用“input”对象。对象mem在DownloadBlobAsStream()中有局部作用域,这就是为什么要设置mem.Position必须在这个函数中完成。但是,当您调用ReadFully()并传递“Stream”对象时,您也可以将其位置设置为0,如我在帖子中所示。因此,这两种方法都被接受并将起作用。如果我在内部轻松设置Position=0,它会抛出一个错误“Not Supported”,当我尝试查看输入属性时,
CanSeek=false
,但您的想法帮助很大。:)只是想澄清一下,您得到的是空值还是空字节数组?我没有看到一个空值,但在测试中看到了一个空字节数组,没有以某种方式改变流的位置。对我来说效果很好。谢谢。请注意-即使blob不存在,blob也不会为空。使用blockBlob.Exists()而不是(blob!=null),那么这是否意味着DownloadToStream实际上没有兑现它的承诺?我认为CloudBlockBlob.OpenRead()可以用来获取一个流,该流可以用来访问blob的部分内容,而不必先下载整个内容。