【问题标题】:How to copy folders from blob storage?如何从 Blob 存储中复制文件夹?
【发布时间】:2021-06-15 14:50:48
【问题描述】:

我试图实现的功能是将粘贴文件/文件夹从一个源复制到另一个(相同的容器)。我可以使用与复制文件相同的方法来复制文件夹吗? startcopyblob() 在复制粘贴文件夹时抛出错误。

输入:

newFileName:'新文件夹_copy1' 新文件路径:'603487d1e966a91fd86b6c11/spe9_rs_2021-03-17_17-14-38/输出' oldFilePath:'603487d1e966a91fd86b6c11/spe9_rs_2021-02-23_11-14-41/output/新文件夹'

错误:

code:'CannotVerifyCopySource'
message:'The specified blob does not exist.
name:'StorageError'
requestId:'4a8a76bf-701e-0078-17c8-1b4439000000'
stack:'StorageError: The specified blob does not exist.
statusCode:404

Uncaught Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

代码:

var host = sasurl.substring(0, sasurl.lastIndexOf("/"));
var containerName = sasurl.substring(sasurl.lastIndexOf("/"), sasurl.indexOf("?")).split("/")[1];
var saskey = sasurl.substring(sasurl.indexOf("?"), sasurl.length);
var blobService = storage.createBlobServiceWithSas(host, saskey);
pasteFiles.forEach(elem => {
var storageuri = host + "/" + containerName + "/" + elem["oldFilePath"] + saskey;
var blobName = elem["newFilePath"] + "/" + elem["newFileName"];
blobService.startCopyBlob(storageuri, containerName, blobName, err => {
if (err) {
console.log(err)
return res.status(500).json({
message: 'error',
status: err
})

..... ..

【问题讨论】:

  • 能否告诉我 sourceContainer 和 desContainer 是否在同一个存储帐户中以及如何创建 sas 令牌?
  • 是的,他们在同一个帐户中。我可以复制文件但对于文件夹,抛出上述错误。
  • 是不是直接把一个文件夹复制到另一个容器里?
  • storageuri='://host/container-name/603487d1e966a91fd86b6c11/spe9_rs_2021-02-23_11-14-41/output/new folder?sv=2019-1........ ....3D' blobname='603487d1e966a91fd86b6c11/spe9_rs_2021-03-17_17-14-38/output/new folder_copy1'
  • 我用的是node js,,blob服务。

标签: node.js azure-blob-storage


【解决方案1】:

Azure Blob 存储具有 2 级层次结构 - Blob 容器和 Blob。它基于平面存储方案,而不是分层方案。它没有目录结构。我们只需在 blob 名称中指定字符或字符串分隔符即可创建虚拟层次结构。所以如果我们想用azure node blob sdk复制一个文件夹,就需要一个一个的复制文件夹中的blob。

例如 sdk

npm i @azure/storage-blob

代码

const {
  BlobServiceClient,
  StorageSharedKeyCredential,
  generateBlobSASQueryParameters,
  ContainerSASPermissions,
} = require("@azure/storage-blob");

const accountName = "andyprivate";
const accountKey =
  "";
const creds = new StorageSharedKeyCredential(accountName, accountKey);
const blobServiceClient = new BlobServiceClient(
  `https://${accountName}.blob.core.windows.net`,
  creds
);
async function test() {
  try {
    const sourceContainerClient = blobServiceClient.getContainerClient("input");
    const desContainerClient = blobServiceClient.getContainerClient("output");
    const blobSAS = generateBlobSASQueryParameters(
      {
        expiresOn: new Date(new Date().valueOf() + 86400000),
        containerName: sourceContainerClient.containerName,
        permissions: ContainerSASPermissions.parse("rl"),
      },
      creds
    ).toString();
    for await (const response of sourceContainerClient
      .listBlobsFlat({ prefix: "<your folder name>/" })
      .byPage()) {
      for (const blob of response.segment.blobItems) {
        console.log(`Blob name : ${blob.name}`);
        const sourceBlob = sourceContainerClient.getBlobClient(blob.name);
        const sourceUrl = sourceBlob.url + "?" + blobSAS;
        const res = await (
          await desContainerClient
            .getBlobClient(blob.name)
            .beginCopyFromURL(sourceUrl)
        ).pollUntilDone();

        console.log(res.copyStatus);
      }
    }
  } catch (error) {
    console.log(error);
  }
}
test();

另外,如果你想直接从一个容器复制一个文件夹到另一个容器,我们可以使用 azcopy 实现。更多详情请参考herehere

例如

npm i @azure/storage-blob @azure-tools/azcopy-node @azure-tools/azcopy-<your system win32 linux win64>
 

代码

const {
  StorageSharedKeyCredential,
  generateAccountSASQueryParameters,
  AccountSASPermissions,
  AccountSASResourceTypes,
  AccountSASServices,
} = require("@azure/storage-blob");

const accountName = "andyprivate";
const accountKey =
  "";
const creds = new StorageSharedKeyCredential(accountName, accountKey);
//create account sas token
const accountSas = generateAccountSASQueryParameters(
  {
    startsOn: new Date(new Date().valueOf() - 8640),
    expiresOn: new Date(new Date().valueOf() + 86400000),
    resourceTypes: AccountSASResourceTypes.parse("sco").toString(),
    permissions: AccountSASPermissions.parse("rwdlacup").toString(),
    services: AccountSASServices.parse("b").toString(),
  },
  creds
).toString();
const { AzCopyClient } = require("@azure-tools/azcopy-node");
let copyClient = new AzCopyClient();

async function copy() {


  try {
    let jobId = await copyClient.copy(
      {
        type: "RemoteSas",
        resourceUri: "https://<>.blob.core.windows.net/input",
        sasToken: accountSas,
        path: "/<folder name>",
      },
      {
        type: "RemoteSas",
        resourceUri: "https://<>.blob.core.windows.net/outcontainer",
        sasToken: accountSas,
        path: "",
      },
      { recursive: true }
    );
    let status;
    while (!status || status.StatusType !== "EndOfJob") {
      let jobInfo = await copyClient.getJobInfo(jobId);
      status = jobInfo.latestStatus;
      await new Promise((resolve, reject) => setTimeout(resolve, 1000));
    }
    console.log("OK");
  } catch (error) {
    console.log(error);
  }
}

copy();

【讨论】:

    猜你喜欢
    • 2023-01-20
    • 2019-03-20
    • 2014-05-10
    • 2021-07-29
    • 2021-11-22
    • 2019-05-18
    • 2019-10-30
    • 1970-01-01
    • 2016-11-25
    相关资源
    最近更新 更多