CloudBlockBlob DownloadTextAsync 行为差异
CloudBlockBlob DownloadTextAsync Behavior Difference
我正在使用带有事件网格触发器和 CloudBlockBlob 作为输入绑定的 azure 函数。使用 DownloadTextAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
从 CloudBlockBob 下载内容
如果上面下载的文件是使用 XmlDocument 生成的,DownloadTextAsync returns 乱码。但是,如果文件是使用 FileStream 生成的,则可以正常工作。 PFB生成文件的实现-
- 使用 XmlDocument
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(typeof(List<ContractName>), new XmlRootAttribute("RootAttributeName"));
serializer.Serialize(stringwriter, contractData);
var xmlString = stringwriter.ToString();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
doc.PreserveWhitespace = true;
doc.Save(fileName);
- 使用文件流
var serializer = new XmlSerializer(typeof(List<ContractName>), new XmlRootAttribute("RootAttributeName"));
var file = new FileStream(fileName, FileMode.OpenOrCreate);
serializer.Serialize(file, contractData);
file.Close();
用于下载内容的代码-
- 使用 DownloadTextAsync
private static async System.Threading.Tasks.Task<string> DownloadContentAsync_DownloadTextAsync(string storageAccountConnectionString, string containerName, string blobName)
{
CloudBlobContainer container = GetContainer(storageAccountConnectionString, containerName);
ICloudBlob blob = await container.GetBlobReferenceFromServerAsync(blobName);
// Download the blob content
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
return xmlBlobContent;
}
- 使用 DownloadToStreamAsync
private static async System.Threading.Tasks.Task<string> DownloadContentAsync_DownloadToStreamAsync(string storageAccountConnectionString, string containerName, string blobName)
{
CloudBlobContainer container = GetContainer(storageAccountConnectionString, containerName);
ICloudBlob blob = await container.GetBlobReferenceFromServerAsync(blobName);
// Download the blob content
MemoryStream resultStream = new MemoryStream();
await (blob as CloudBlockBlob).DownloadToStreamAsync(
resultStream,
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
string xmlBlobContent = System.Text.Encoding.UTF8.GetString(resultStream.ToArray());
return xmlBlobContent;
}
为什么 DownloadTextAsync 的响应不同。
更新 0713:
想通了。根本原因是当您使用 XmlDocument
生成 xml
文件时,编码是 utf-16
。但是对于 FileStream
,它会生成编码为 utf-8
.
的 xml 文件
所以,解决方案是,当使用XmlDocument
时,我们可以将编码指定为utf-8
(FileStream
无需更改代码)。示例代码如下:
生成 xml 文件使用 XmlDocument
:
//2. Using XMLDoc
serializer.Serialize(stringwriter, contractData);
var xmlString = stringwriter.ToString();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
doc.PreserveWhitespace = true;
string fileName = String.Format(@"C:\TestBlobDownloadContent\UsingXMLDoc" + count + ".xml");
//encoding as utf-8
using (TextWriter sw = new StreamWriter(fileName, false, Encoding.UTF8))
{
doc.Save(sw);
}
通过DownloadTextAsync()
方法从blob存储中读取xml文件时,无需指定编码选项,如下所示:
// Download the blob content
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
原回答:
这是由于 encode/decode 问题造成的。
解决方案:
在DownloadTextAsync()
方法中,添加参数System.Text.Encoding.Unicode
。如下所示:
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
System.Text.Encoding.Unicode,
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
测试结果:
我正在使用带有事件网格触发器和 CloudBlockBlob 作为输入绑定的 azure 函数。使用 DownloadTextAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
从 CloudBlockBob 下载内容如果上面下载的文件是使用 XmlDocument 生成的,DownloadTextAsync returns 乱码。但是,如果文件是使用 FileStream 生成的,则可以正常工作。 PFB生成文件的实现-
- 使用 XmlDocument
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(typeof(List<ContractName>), new XmlRootAttribute("RootAttributeName"));
serializer.Serialize(stringwriter, contractData);
var xmlString = stringwriter.ToString();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
doc.PreserveWhitespace = true;
doc.Save(fileName);
- 使用文件流
var serializer = new XmlSerializer(typeof(List<ContractName>), new XmlRootAttribute("RootAttributeName"));
var file = new FileStream(fileName, FileMode.OpenOrCreate);
serializer.Serialize(file, contractData);
file.Close();
用于下载内容的代码-
- 使用 DownloadTextAsync
private static async System.Threading.Tasks.Task<string> DownloadContentAsync_DownloadTextAsync(string storageAccountConnectionString, string containerName, string blobName)
{
CloudBlobContainer container = GetContainer(storageAccountConnectionString, containerName);
ICloudBlob blob = await container.GetBlobReferenceFromServerAsync(blobName);
// Download the blob content
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
return xmlBlobContent;
}
- 使用 DownloadToStreamAsync
private static async System.Threading.Tasks.Task<string> DownloadContentAsync_DownloadToStreamAsync(string storageAccountConnectionString, string containerName, string blobName)
{
CloudBlobContainer container = GetContainer(storageAccountConnectionString, containerName);
ICloudBlob blob = await container.GetBlobReferenceFromServerAsync(blobName);
// Download the blob content
MemoryStream resultStream = new MemoryStream();
await (blob as CloudBlockBlob).DownloadToStreamAsync(
resultStream,
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
string xmlBlobContent = System.Text.Encoding.UTF8.GetString(resultStream.ToArray());
return xmlBlobContent;
}
为什么 DownloadTextAsync 的响应不同。
更新 0713:
想通了。根本原因是当您使用 XmlDocument
生成 xml
文件时,编码是 utf-16
。但是对于 FileStream
,它会生成编码为 utf-8
.
所以,解决方案是,当使用XmlDocument
时,我们可以将编码指定为utf-8
(FileStream
无需更改代码)。示例代码如下:
生成 xml 文件使用 XmlDocument
:
//2. Using XMLDoc
serializer.Serialize(stringwriter, contractData);
var xmlString = stringwriter.ToString();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
doc.PreserveWhitespace = true;
string fileName = String.Format(@"C:\TestBlobDownloadContent\UsingXMLDoc" + count + ".xml");
//encoding as utf-8
using (TextWriter sw = new StreamWriter(fileName, false, Encoding.UTF8))
{
doc.Save(sw);
}
通过DownloadTextAsync()
方法从blob存储中读取xml文件时,无需指定编码选项,如下所示:
// Download the blob content
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
原回答:
这是由于 encode/decode 问题造成的。
解决方案:
在DownloadTextAsync()
方法中,添加参数System.Text.Encoding.Unicode
。如下所示:
string xmlBlobContent =
await (blob as CloudBlockBlob).DownloadTextAsync(
System.Text.Encoding.Unicode,
null,
new BlobRequestOptions { LocationMode = LocationMode.PrimaryThenSecondary },
new OperationContext());
测试结果: