从未以任何格式压缩的 azure blob 存储下载文件夹
Posted
技术标签:
【中文标题】从未以任何格式压缩的 azure blob 存储下载文件夹【英文标题】:Download a folder from azure blob storage which is not compressed in any format 【发布时间】:2021-08-21 07:29:15 【问题描述】:我正在尝试下载未以 .zip、7-zip 等任何格式压缩的文件夹。我从Get azure blob files from inside Sub Directories using php获取代码。
我在 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);
【问题讨论】:
请编辑您的问题并包含您编写的代码。很遗憾,您提供的信息不足以提供答案。 @GauravMantri 感谢您的建议。我更新了代码。 【参考方案1】:只需尝试下面的代码,使用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.";
?>
我已经测试过了,请看下面的结果: 我的斑点:
【讨论】:
【参考方案2】:您的方法不起作用,因为 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。
【讨论】:
以上是关于从未以任何格式压缩的 azure blob 存储下载文件夹的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 中的 Azure.Storage.Blobs 从 Azure 存储 Blob 以 ByteArray 格式获取文件
如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?