我试图实现的功能是将粘贴文件/文件夹从一个源复制到另一个(同一容器)。我可以像复制文件一样使用相同的方法复制文件夹吗? startcopyblob() 在复制粘贴文件夹时抛出错误。
输入:
newFileName:'新文件夹_copy1' 新文件路径:'603487d1e966a91fd86b6c11/spe9_rs_2021-03-17_17-14-38/output' oldFilePath:'603487d1e966a91fd86b6c11/spe9_rs_2021-02-23_11-14-41/output/new folder'
错误:
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
})
..... ..
答案 0 :(得分:0)
Azure blob 存储有 2 级层次结构 - blob 容器和 blob。它基于平面存储方案,而不是分层方案。它没有目录结构。我们只需在 blob 名称中指定字符或字符串分隔符即可创建虚拟层次结构。所以如果我们要复制一个带有azure node blob sdk的文件夹,就需要将文件夹中的blobs一个一个的复制。
例如 开发包
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 实现它。详情请参阅here和here
例如
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();