使用 Azure 函数从 Azure Blob 存储下载文件会返回不同的文件大小

Posted

技术标签:

【中文标题】使用 Azure 函数从 Azure Blob 存储下载文件会返回不同的文件大小【英文标题】:Downloading files from Azure Blob Storage using Azure Function returns different file size 【发布时间】:2021-05-11 20:58:42 【问题描述】:

我们正在尝试使用 Azure 函数为托管在 Azure blob 存储中的文件提供服务。获取它们时,我们收到以下错误:

Uncaught (in promise) Error: Length in header does not match actual data length: X != Y

我对这类事情不是很精通,但我们的开发人员正在绞尽脑汁,我也一无所获。

我们认为罪魁祸首的 Azure 函数中的 sn-p 是:

const streamToBuffer = async (readableStream) => 
  return new Promise((resolve, reject) => 
    const chunks = [];
    readableStream.on('data', (data) => 
      chunks.push(data instanceof Buffer ? data : Buffer.from(data));
    );
    readableStream.on('end', () => 
      resolve(Buffer.concat(chunks));
    );
    readableStream.on('error', reject);
  );
;

编辑:

    const blobClient = containerClient.getBlobClient(path);

    if (await blobClient.exists()) 
      const downloadBlockBlobResponse = await blobClient.download();

      const content = (
        await streamToBuffer(downloadBlockBlobResponse.readableStreamBody)
      ).toString();

编辑2:

跟踪中的错误:

Uncaught (in promise) Error: Can not parse environment file at god3.js:16
Uncaught (in promise) Error: Length in header does not match actual data length: X != Y
Error while trying to use the following icon from the Manifest: $url (Download error or resource isn't a valid image)

我们仅在通过 Azure 函数提供数据时遇到此问题。我们已尝试将逻辑托管在不同的平台上,并且在拉取文件时可以正常工作。

函数的附加部分:

  const containerClient = blobServiceClient.getContainerClient('site');

    const blobClient = containerClient.getBlobClient(path);

    if (await blobClient.exists()) 
      const downloadBlockBlobResponse = await blobClient.download();

      const content = (
        await streamToBuffer(downloadBlockBlobResponse.readableStreamBody)
      ).toString();

      context.res = 
        headers: 
          'Content-Type': downloadBlockBlobResponse.contentType,
        ,
        body: content,
      ;
     else 
      context.res = 
        status: 404,
      ;
    
   else 
    context.res = 
      status: 401,
      headers:  'WWW-Authenticate': 'Basic realm=Access to the staging site' ,
      body:  success: false ,
    ;
  
;

任何指针将不胜感激。

谢谢

【问题讨论】:

@DorisLv 用于 .Net SDK。我们正在关注这个:docs.microsoft.com/en-us/azure/storage/blobs/… 你能发布完整的异常堆栈吗?错误消息显然不是来自您的代码。您是否也尝试过同步接口(@98​​7654327@)而不是异步?最后,您是否尝试过使用不同的 blob?只是为了确保它不是真正损坏的 blob。 @Kashyap 我们没有尝试过同步接口,可以。我们可以在不使用 Azure Functions 时从同一个 blob 中提取数据,所以我们没有尝试过不同的 blob。但这样做只是为了确保我们得到同样的问题。 【参考方案1】:

我们发现了问题。

我们正在对二进制文件进行字符串化,BabylonJS 不喜欢。

解决方案是在函数中添加文件类型检查。

      const content = await streamToBuffer(
        downloadBlockBlobResponse.readableStreamBody,
      );
      const fileType = path.split('.').slice(-1)[0];
      context.res = 
        headers: 
          'Content-Type': downloadBlockBlobResponse.contentType,
        ,
        body: textPlainType.has(fileType) ? content : content.toString(),
      ;

【讨论】:

以上是关于使用 Azure 函数从 Azure Blob 存储下载文件会返回不同的文件大小的主要内容,如果未能解决你的问题,请参考以下文章

使用 Azure 函数从 Azure Blob 存储下载文件会返回不同的文件大小

Azure:无法从 Azure 函数 HttpTrigger 读取 Blob 文本(400 - 错误请求错误)

使用java中的azure函数将文件从浏览器上传到azure blob存储

使用 azure 函数从表单数据请求中详细说明并存储在 azure blob 中的多个文件

如何从 HTTP 触发的 Azure 函数返回 blob?

Azure 函数从门户或 Visual Studio-Blob 触发器执行