Search code examples
node.jsazure-storageazure-blob-storageazure-node-sdk

Copy blob from one storage account to another using @azure/storage-blob


What would be the best way to copy a blob from one storage account to another storage account using @azure/storage-blob?

I would imagine using streams would be best instead of downloading and then uploading, but would like to know if the code below is the correct/optimal implementation for using streams.

const srcCredential = new ClientSecretCredential(<src-ten-id>, <src-client-id>, <src-secret>);
const destCredential = new ClientSecretCredential(<dest-ten-id>, <dest-client-id>, <dest-secret>);

const srcBlobClient = new BlobServiceClient(<source-blob-url>, srcCredential);
const destBlobClient = new BlobServiceClient(<dest-blob-url>, destCredential);

const sourceContainer = srcBlobClient.getContainerClient("src-container");
const destContainer = destBlobClient.getContainerClient("dest-container");

const sourceBlob = sourceContainer.getBlockBlobClient("blob");
const destBlob = destContainer.getBlockBlobClient(sourceBlob.name)

// copy blob
await destBlob.uploadStream((await sourceBlob.download()).readableStreamBody);

Solution

  • Your current approach downloads the source blob and then re-uploads it which is not really optimal.

    A better approach would be to make use of async copy blob. The method you would want to use is beginCopyFromURL(string, BlobBeginCopyFromURLOptions). You would need to create a Shared Access Signature URL on the source blob with at least Read permission. You can use generateBlobSASQueryParameters SDK method to create that.

    const sourceBlob = sourceContainer.getBlockBlobClient("blob");
    const destBlob = destContainer.getBlockBlobClient(sourceBlob.name);
    
    const sourceBlobSasUrl = GenerateSasUrlWithReadPermissionOnSourceBlob(sourceBlob);
    // copy blob
    await destBlob.beginCopyFromURL(sourceBlobSasUrl);