Azure-sdk-for-js: downloadBlockBlobResponse.readableStreamBody in node js not downloading the whole file

Created on 26 Sep 2019  路  11Comments  路  Source: Azure/azure-sdk-for-js

  • Package Name: @azure/storage-blob
  • Package Version: 10.5
  • Operating system: Windows 10
  • [ ] nodejs

    • version: 10

  • [ ] typescript

    • version:

  • Is the bug related to documentation in

    • [ ] README.md

Describe the bug
i am following what is mentioned in "getting started" and code sample. My requirement is to download a zip file from blob to a predefined location and upload it in release pipeline of Azure devops task.
The issue is using this command
var data = downloadBlockBlobResponse.readableStreamBody;
fileSystem.writeFile(fileName, data);

is copying only 1kb data and exiting. Can you please let me know what is wrong here.

Client Service Attention Storage customer-reported question

Most helpful comment

@kriti218
I believe since you're using the readableStreamBody, you'll want to first create a writeable stream to the filesystem using fs.createWriteStream then pipe the readableStreamBody into that:

// error handlers should also be added
const fileStream = fs.createWriteStream("/path/to/destination");
downloadBlockBlobResponse.readableStreamBody.pipe(fileStream);

There is also the downloadToFile method to make downloading a blob to a file easier as long as the file doesn't already exist on your system.

All 11 comments

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage

If anyone can help ASAP that will be great as I am blocked and see no other way out reading the limited documentation provided on your site

@kriti218
I believe since you're using the readableStreamBody, you'll want to first create a writeable stream to the filesystem using fs.createWriteStream then pipe the readableStreamBody into that:

// error handlers should also be added
const fileStream = fs.createWriteStream("/path/to/destination");
downloadBlockBlobResponse.readableStreamBody.pipe(fileStream);

There is also the downloadToFile method to make downloading a blob to a file easier as long as the file doesn't already exist on your system.

Thanks @chradek for unblocking me. Can i give "sas url to the blob file" in place of blob file path in "downloadToFile" method?

@kriti218 you can create an instance of BlobClient directly using the constructor that takes a url (the doc for overloads doesn't show until you click on them though) , then call the downloadToFile function
image

i did that but i am getting error "BlobClient is not a constructor".

import * as Azure from "@azure/storage-blob";
BlobClient seems to be absent from "Azure' imported from package. Any inputs please?

var blobClient = new BlobClient('sas url of blob file');

@kriti218
Apologies, downloadToFile is available on the preview version of the @azure/storage-blob SDK (version 12), not version 10.x.

To accomplish what you want to do with version 10.5 of the SDK, you can do something like the following:

const { createWriteStream} = require('fs');
const { join } = require('path');
const { BlobURL, Aborter, StorageURL, AnonymousCredential } = require('@azure/storage-blob');

async function run() {
  const blobUrl = new BlobURL(
    'MY-SAS-CONNECTION-STRING',
    StorageURL.newPipeline(new AnonymousCredential())
  );

  const blob = await blobUrl.download(Aborter.none, 0);
  // does not check if file already exists on system
  await downloadToFile(join(__dirname, 'test.txt'), blob);
}

function downloadToFile(path, blob) {
  return new Promise((resolve, reject) => {
    const fileStream = createWriteStream(path);
    blob.readableStreamBody.on('error', reject);
    fileStream.on('error', reject);
    fileStream.on('close', resolve);
    blob.readableStreamBody.pipe(fileStream);
  });
}

run();

If you're interested in trying out the preview version of the SDK, you can install it by running npm install @azure/storage-blob@next. There may be breaking changes between preview versions, but we'd love to get feedback if you have time to try it!

Here's what the equivalent code looks like in the preview version of the SDK:

const { join } = require('path');
const { BlobClient } = require('@azure/storage-blob');

async function run() {
  const client = new BlobClient(
    'MY-SAS-CONNECTION-STRING'
  );

  // Checks if file exists on system and throws error if it does
  await client.downloadToFile(join(__dirname, 'test.txt'));
}

run();

The preview version looks far better but i have to deploy these changes in production so would not be willing to use "preview" version as that might break because of continuous changes. Thanks!

One feedback, please improve the documentation by giving some examples as it is easy to understand.

@XiaoningLiu can we consider closing this issue as we have provided guidance on the approach to take with V12 SDK for js

Hi, in latest commits, we provided detialed samples and references for storage SDKs. Will close this issue.

Was this page helpful?
0 / 5 - 0 ratings