从未以任何格式压缩的 azure blob 存储下载文件夹
Download a folder from azure blob storage which is not compressed in any format
我正在尝试下载一个未压缩为任何格式(如 .zip、7-zip)的文件夹。我从 .
中获取了代码
我在 Azure Blob 存储上的文件夹结构就是这样 parentFolder>childFolder>1.pdf,2.pdf,3.pdf
。
我正在尝试下载 childFolder
。我正在使用下面的代码,但出现错误 BlobNotFoundThe specified blob does not exist.
<?php
$storageAccount = 'XXXXXXX';
$containerName = 'XXXXXXX';
$blobName = 'parentFolder/childFolder';
$account_key = 'XXXXXXXXXXXXXXXXXXXXX';
$date = gmdate('D, d M Y H:i:s \G\M\T');
$version = "2019-12-12";
$stringtosign = "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:". $date . "\nx-ms-version:".$version."\n/".$storageAccount."/".$containerName."/".$blobName;
$signature = 'SharedKey'.' '.$storageAccount.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));
echo "\n\n" . $signature;
$header = array (
"x-ms-date: " . $date,
"x-ms-version: " . $version,
"Authorization: " . $signature
);
$url="https://$storageAccount.blob.core.windows.net/$containerName/$blobName";
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header);
curl_exec ( $ch );
$result = curl_exec($ch);
echo "\n\n" . $result;
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
file_put_contents('C://demo//childFolder', $result); // save the string to a file
curl_close($ch);
您的方法行不通,因为 Azure Blob 存储中的文件夹不是真正的文件夹。它们是虚拟文件夹。您的 blob 名称是 parentFolder/childFolder/1.pdf
等等。
要从虚拟文件夹下载 blob,您需要执行以下操作:
- 列出 blob 容器中的 blob。由于您只想从
parentFolder/childFolder
下载 blob,因此您必须进行 prefix
搜索。这将列出所需文件夹中的所有 blob。
- 获得列表后,您可以从该列表下载每个 blob。
不幸的是,我对 PHP 了解不多,因此我只给你一些指导(而不是代码)。
我还建议使用 Azure Storage SDK for PHP
而不是直接使用 REST API。这将使您的工作更加轻松。您可以在此处找到有关 SDK 的更多信息:https://github.com/Azure/azure-storage-php.
只需尝试下面的代码,使用 sasToken
和 cURL
下载文件夹下的所有 blob:
<?php
function generateSharedAccessSignature($accountName,
$storageKey,
$signedPermissions,
$signedService,
$signedResourceType,
$signedStart,
$signedExpiry,
$signedIP,
$signedProtocol,
$signedVersion){
if(empty($accountName)){
trigger_error("The account name is required.");
return;
}
if(empty($storageKey)){
trigger_error("The account key is required.");
return;
}
if(empty($signedPermissions)){
trigger_error("The permissions are required.");
return;
}
if(empty($signedService)){
trigger_error("The services are required.");
return;
}
if(empty($signedResourceType)){
trigger_error("The resource types are required.");
return;
}
if(empty($signedExpiry)){
trigger_error("The expiration time is required.");
return;
}
if(empty($signedVersion)){
trigger_error("The service version is required.");
return;
}
// generate the string to sign
$_toSign = urldecode($accountName) . "\n" .
urldecode($signedPermissions) . "\n" .
urldecode($signedService) . "\n" .
urldecode($signedResourceType) . "\n" .
urldecode($signedStart) . "\n" .
urldecode($signedExpiry) . "\n" .
urldecode($signedIP) . "\n" .
urldecode($signedProtocol) . "\n" .
urldecode($signedVersion) . "\n";
// sign the string using hmac sha256 and get a base64 encoded version_compare
$_signature = base64_encode(hash_hmac("sha256", utf8_encode($_toSign), base64_decode($storageKey), true));
return $_signature;
}
$key= "";
$storageAccount = "";
$containerName = "";
$directoryName = "";
$destDir = "d:/temp/";
$_signedPermissions = "rl"; //read and list permission
$_signedService = "b"; // for blob service
$_signedResourceType = "oc"; //only for access container and object
$_signedStart = "2021-05-31T00:00:00Z"; //sas token start time
$_signedExpiry = "2021-06-10T00:00:00Z"; //sas token expairy time
$_signedIP = NULL; // no IP limit
$_signedProtocol = "https";
$_signedVersion = "2020-02-10";
$_signature = generateSharedAccessSignature($storageAccount,
$key,
$_signedPermissions,
$_signedService,
$_signedResourceType,
$_signedStart,
$_signedExpiry,
$_signedIP,
$_signedProtocol,
$_signedVersion);
$sig = urlencode($_signature);
$sasToken = "sp=$_signedPermissions&srt=$_signedResourceType&ss=$_signedService&st=$_signedStart&se=$_signedExpiry&sv=$_signedVersion&spr=$_signedProtocol&sig=$sig";
$destinationURL = "https://$storageAccount.blob.core.windows.net/$containerName?restype=container&comp=list&prefix=$directoryName&$sasToken";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $destinationURL);
$content = curl_exec($ch);
$xml = simplexml_load_string($content);
foreach ($xml->Blobs->Blob as $i) {
$url ="https://$storageAccount.blob.core.windows.net/$containerName/$i->Name";
//Use basename() function to return the base name of file
$file_name = $destDir.basename($url) ;
//Use file_get_contents() function to get the file
//from url and use file_put_contents() function to
//save the file by using base name
if(file_put_contents( $file_name,file_get_contents($url."?".$sasToken ))) {
echo "$url:File downloaded successfully\n";
}
else {
echo "File downloading failed.";
}
}
?>
我这边测试过,结果如下:
我的斑点:
我正在尝试下载一个未压缩为任何格式(如 .zip、7-zip)的文件夹。我从
我在 Azure Blob 存储上的文件夹结构就是这样 parentFolder>childFolder>1.pdf,2.pdf,3.pdf
。
我正在尝试下载 childFolder
。我正在使用下面的代码,但出现错误 BlobNotFoundThe specified blob does not exist.
<?php
$storageAccount = 'XXXXXXX';
$containerName = 'XXXXXXX';
$blobName = 'parentFolder/childFolder';
$account_key = 'XXXXXXXXXXXXXXXXXXXXX';
$date = gmdate('D, d M Y H:i:s \G\M\T');
$version = "2019-12-12";
$stringtosign = "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:". $date . "\nx-ms-version:".$version."\n/".$storageAccount."/".$containerName."/".$blobName;
$signature = 'SharedKey'.' '.$storageAccount.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));
echo "\n\n" . $signature;
$header = array (
"x-ms-date: " . $date,
"x-ms-version: " . $version,
"Authorization: " . $signature
);
$url="https://$storageAccount.blob.core.windows.net/$containerName/$blobName";
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header);
curl_exec ( $ch );
$result = curl_exec($ch);
echo "\n\n" . $result;
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
file_put_contents('C://demo//childFolder', $result); // save the string to a file
curl_close($ch);
您的方法行不通,因为 Azure Blob 存储中的文件夹不是真正的文件夹。它们是虚拟文件夹。您的 blob 名称是 parentFolder/childFolder/1.pdf
等等。
要从虚拟文件夹下载 blob,您需要执行以下操作:
- 列出 blob 容器中的 blob。由于您只想从
parentFolder/childFolder
下载 blob,因此您必须进行prefix
搜索。这将列出所需文件夹中的所有 blob。 - 获得列表后,您可以从该列表下载每个 blob。
不幸的是,我对 PHP 了解不多,因此我只给你一些指导(而不是代码)。
我还建议使用 Azure Storage SDK for PHP
而不是直接使用 REST API。这将使您的工作更加轻松。您可以在此处找到有关 SDK 的更多信息:https://github.com/Azure/azure-storage-php.
只需尝试下面的代码,使用 sasToken
和 cURL
下载文件夹下的所有 blob:
<?php
function generateSharedAccessSignature($accountName,
$storageKey,
$signedPermissions,
$signedService,
$signedResourceType,
$signedStart,
$signedExpiry,
$signedIP,
$signedProtocol,
$signedVersion){
if(empty($accountName)){
trigger_error("The account name is required.");
return;
}
if(empty($storageKey)){
trigger_error("The account key is required.");
return;
}
if(empty($signedPermissions)){
trigger_error("The permissions are required.");
return;
}
if(empty($signedService)){
trigger_error("The services are required.");
return;
}
if(empty($signedResourceType)){
trigger_error("The resource types are required.");
return;
}
if(empty($signedExpiry)){
trigger_error("The expiration time is required.");
return;
}
if(empty($signedVersion)){
trigger_error("The service version is required.");
return;
}
// generate the string to sign
$_toSign = urldecode($accountName) . "\n" .
urldecode($signedPermissions) . "\n" .
urldecode($signedService) . "\n" .
urldecode($signedResourceType) . "\n" .
urldecode($signedStart) . "\n" .
urldecode($signedExpiry) . "\n" .
urldecode($signedIP) . "\n" .
urldecode($signedProtocol) . "\n" .
urldecode($signedVersion) . "\n";
// sign the string using hmac sha256 and get a base64 encoded version_compare
$_signature = base64_encode(hash_hmac("sha256", utf8_encode($_toSign), base64_decode($storageKey), true));
return $_signature;
}
$key= "";
$storageAccount = "";
$containerName = "";
$directoryName = "";
$destDir = "d:/temp/";
$_signedPermissions = "rl"; //read and list permission
$_signedService = "b"; // for blob service
$_signedResourceType = "oc"; //only for access container and object
$_signedStart = "2021-05-31T00:00:00Z"; //sas token start time
$_signedExpiry = "2021-06-10T00:00:00Z"; //sas token expairy time
$_signedIP = NULL; // no IP limit
$_signedProtocol = "https";
$_signedVersion = "2020-02-10";
$_signature = generateSharedAccessSignature($storageAccount,
$key,
$_signedPermissions,
$_signedService,
$_signedResourceType,
$_signedStart,
$_signedExpiry,
$_signedIP,
$_signedProtocol,
$_signedVersion);
$sig = urlencode($_signature);
$sasToken = "sp=$_signedPermissions&srt=$_signedResourceType&ss=$_signedService&st=$_signedStart&se=$_signedExpiry&sv=$_signedVersion&spr=$_signedProtocol&sig=$sig";
$destinationURL = "https://$storageAccount.blob.core.windows.net/$containerName?restype=container&comp=list&prefix=$directoryName&$sasToken";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $destinationURL);
$content = curl_exec($ch);
$xml = simplexml_load_string($content);
foreach ($xml->Blobs->Blob as $i) {
$url ="https://$storageAccount.blob.core.windows.net/$containerName/$i->Name";
//Use basename() function to return the base name of file
$file_name = $destDir.basename($url) ;
//Use file_get_contents() function to get the file
//from url and use file_put_contents() function to
//save the file by using base name
if(file_put_contents( $file_name,file_get_contents($url."?".$sasToken ))) {
echo "$url:File downloaded successfully\n";
}
else {
echo "File downloading failed.";
}
}
?>
我这边测试过,结果如下:
我的斑点: