azure - 尝试将 HttpClient.GetStreamAsync 直接用于 adls FileClient.UploadAsync
问题描述
我有一个 Azure 函数,它将通过 HttpClient 调用外部 API。外部 API 返回 JSON 响应。我想将响应直接保存到 ADLS 文件。
我的简单代码是:
public async Task UploadFileBulk(Stream contentToUpload)
{
await this._theClient.FileClient.UploadAsync(contentToUpload);
}
this._theClient 是围绕各种 Azure Data Lake 类(如 DataLakeServiceClient、DataLakeFileSystemClient、DataLakeDirectoryClient、DataLakeFileClient)的简单包装类。
我很高兴这个包装器调用按我的预期工作,我启动一个,设置服务、文件系统、目录,然后创建一个文件名。我已经使用这个包装类来创建目录等,所以它可以按我的预期工作。
我将上述方法调用如下:
await dlw.UploadFileBulk(await this._httpClient.GetStreamAsync("<endpoint>"));
我看到在 Lake 目录中创建了我想要的文件,但是如果我然后使用 Sorage Explorer 下载文件,然后尝试以 VS Code 的形式打开它,它不是可识别的格式(我可以“强制”代码打开它,但对我来说它看起来像二进制格式)。
如果我用 fiddler 嗅探流量,我可以看到来自外部 API 的内容是 JSON,内容类型是 application/json,body 在 fiddler 中显示为 JSON。
如果我查看对 ADLS 端点的调用,我可以看到一个 PUT 调用,然后是两个 PATCH 调用。
第一个 PATCH 调用看起来像是发送内容的调用,它有一个 application/octet-stream 的内容标头,请求正文是“二进制内容”。
我正在使用 HttpClient.GetStreamAsync 因为我不希望我的函数必须将整个 API 有效负载加载到内存中(一些外部 API 端点返回超过 100mb 的非常大的文件)。我想我可以“将来自外部 API 的响应直接流式传输到 ADLS”。
有没有办法改变 ADLS FileClient.UploadAsync(Stream stream) 方法的工作方式,以便我可以告诉它将文件作为 JSON 文件上传,内容类型为 application/json?
编辑:事实证明,外部 API 正在发送回压缩内容,因此,一旦我将以下额外的 AutomaticDecompression 代码添加到我的函数启动中,我就会按预期将文件上传到 ADLS。
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient("default", client =>
{
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
});
}
@Gaurav Mantri 给了我一些关于“从输出到输入的流”模式是否真的正确的指示,我将进一步研究。
解决方案
关于这个问题,请参考以下代码
var uploadOptions = new DataLakeFileUploadOptions();
uploadOptions.HttpHeaders = new PathHttpHeaders();
uploadOptions.HttpHeaders.ContentType ="application/json";
await fileClient.UploadAsync(stream, uploadOptions);
推荐阅读
- python - 从 SQL Server 代理运行 Powershell 脚本(运行其他 exe 文件)
- junit - 在 Maven 中没有选择测试类
- android - VideoView加载时为黑色,如何显示第一帧或预览?
- c# - 如何在 c# 中存储坐标以在图形引擎中使用
- r - 第一行,其中一列中的值高于另一列 R
- cordova - 生成 apk 后裁剪显示的 Ionic 应用程序图标的图像
- css - 如何在 React Native 上向上滑动扩展 Flatlist
- sharepoint - 更改共享点列表状态的 URL
- amazon-web-services - 如何在 AWS 或云中运行 .robot 文件来触发机器人?
- java - 寻找替代方法来创建 JSON 对象,而不是使用 Json.createObjectBuilder