OSS中檔案數量龐大時,所有檔案平鋪儲存會導致尋找困難、大量操作複雜。為瞭解決這些問題,OSS提供了目錄功能,通過類比檔案夾的結構來組織和管理海量對象。
工作原理
OSS本質上是扁平儲存,沒有真正的檔案夾。控制台所顯示的“目錄”是OSS依據檔案名稱中的/分隔字元自動產生的。
當在控制台看到如下的層級結構時:
examplebucket
└── log/
├── date1.txt
├── date2.txt
├── date3.txt
└── destfolder/
└── 2021/
├── photo.jpg實際上OSS只是儲存了這些檔案:
log/date1.txt
log/date2.txt
destfolder/2021/photo.jpg建立目錄
目錄產生有兩種方式:
上傳檔案時自動產生:上傳包含路徑的檔案時,相應的目錄會自動出現。
主動建立空目錄:此操作的本質是建立一個以
/結尾的0位元組檔案,以此作為空白目錄的預留位置。控制台
在OSS管理主控台,進入目標Bucket的檔案管理 > 檔案清單頁面。
單擊新建目錄。
輸入目錄名,然後單擊確定。
目錄命名規範如下:
- 不允許使用Emoji,請使用符合要求的UTF-8字元。
- 正斜線
/用於分割路徑,可快速建立子目錄,但不要以正斜線/或反斜線\開頭,不要出現連續的正斜線/。 - 不允許出現名為
..的子目錄。 - 總長度控制在1~254個字元。
ossutil
以下樣本展示了如何在儲存空間
examplebucket中建立目錄dir/。ossutil mkdir oss://examplebucket/dir更多用法見mkdir(建立目錄)。
SDK
以下僅列舉常見SDK建立目錄的程式碼範例。關於其他SDK的建立目錄的程式碼範例,請參見SDK簡介。
import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import java.io.ByteArrayInputStream; public class Demo { public static void main(String[] args) throws Exception { // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。運行本程式碼範例之前,請先配置環境變數。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫Bucket名稱,例如examplebucket。 String bucketName = "examplebucket"; // 填寫通過方式一建立的目錄名稱。 String dirName = "exampledir/"; // 填寫通過方式二建立的目錄名稱。 String dirName2 = "exampledir1/"; // 建立OSSClient執行個體。 OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 方式一:通過createDirectory介面直接建立目錄。使用該方法建立目錄前,需要開啟階層命名空間。 ossClient.createDirectory(bucketName, dirName); // 方式二:通過上傳Null 字元串的形式建立目錄。 ossClient.putObject(bucketName, dirName2, new ByteArrayInputStream("".getBytes())); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }<?php if (is_file(__DIR__ . '/../autoload.php')) { require_once __DIR__ . '/../autoload.php'; } if (is_file(__DIR__ . '/../vendor/autoload.php')) { require_once __DIR__ . '/../vendor/autoload.php'; } use OSS\Credentials\EnvironmentVariableCredentialsProvider; use OSS\OssClient; use OSS\CoreOssException; // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 $provider = new EnvironmentVariableCredentialsProvider(); // yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 $endpoint = "yourEndpoint"; // 填寫Bucket名稱,例如examplebucket。 $bucket= "examplebucket"; // 填寫目錄名稱,目錄需以正斜線結尾。 $object = "exampledir/"; $content = ""; try{ $config = array( "provider" => $provider, "endpoint" => $endpoint, ); $ossClient = new OssClient($config); $ossClient->putObject($bucket, $object, $content); } catch(OssException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . "OK" . "\n"); // 上傳時可以設定相關的headers,例如設定存取權限為private、自訂中繼資料等。 $options = array( OssClient::OSS_HEADERS => array( 'x-oss-object-acl' => 'private', 'x-oss-meta-info' => 'your info' ), ); try{ $config = array( "provider" => $provider, "endpoint" => $endpoint, ); $ossClient = new OssClient($config); $ossClient->putObject($bucket, $object, $content, $options); } catch(OssException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . "OK" . "\n");const OSS = require('ali-oss'); const client = new OSS({ // yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。 region: 'yourregion', // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, // 填寫Bucket名稱。 bucket: 'examplebucket', }); async function putBuffer () { try { // 填寫目錄名稱,目錄需以正斜線結尾。 const result = await client.put('exampledir/', new Buffer('')); console.log(result); } catch (e) { console.log(e); } } putBuffer();# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 # 填寫Bucket名稱。 bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket') # 填寫目錄名稱,目錄需以正斜線結尾。 bucket.put_object('exampledir/', '')using System.Text; using Aliyun.OSS; // yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 var endpoint = "yourEndpoint"; // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID"); var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET"); // 填寫Bucket名稱,例如examplebucket。 var bucketName = "examplebucket"; // 填寫目錄名稱,目錄需以正斜線結尾。 var objectName = "exampledir/"; var objectContent = ""; // 建立OssClient執行個體。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { byte[] binaryData = Encoding.ASCII.GetBytes(objectContent); MemoryStream requestContent = new MemoryStream(binaryData); // 建立目錄。 client.PutObject(bucketName, objectName, requestContent); Console.WriteLine("Put object succeeded"); } catch (Exception ex) { Console.WriteLine("Put object failed, {0}", ex.Message); }#include "oss_api.h" #include "aos_http_io.h" /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/ const char *endpoint = "yourEndpoint"; /* 填寫Bucket名稱,例如examplebucket。*/ const char *bucket_name = "examplebucket"; /* 填寫目錄名稱,目錄需以正斜線結尾。*/ const char *object_name = "exampledir/"; const char *object_content = ""; void init_options(oss_request_options_t *options) { options->config = oss_config_create(options->pool); /* 用char*類型的字串初始化aos_string_t類型。*/ aos_str_set(&options->config->endpoint, endpoint); /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/ aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID")); aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET")); /* 是否使用了CNAME。0表示不使用。*/ options->config->is_cname = 0; /* 設定網路相關參數,比如逾時時間等。*/ options->ctl = aos_http_controller_create(options->pool, 0); } int main(int argc, char *argv[]) { /* 在程式入口調用aos_http_io_initialize方法來初始化網路、記憶體等全域資源。*/ if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { exit(1); } /* 用於記憶體管理的記憶體池(pool),等價於apr_pool_t。其實現代碼在apr庫中。*/ aos_pool_t *pool; /* 重新建立一個記憶體池,第二個參數是NULL,表示沒有繼承其它記憶體池。*/ aos_pool_create(&pool, NULL); /* 建立並初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全域配置資訊。*/ oss_request_options_t *oss_client_options; /* 在記憶體池中分配記憶體給options。*/ oss_client_options = oss_request_options_create(pool); /* 初始化Client的選項oss_client_options。*/ init_options(oss_client_options); /* 初始化參數。*/ aos_string_t bucket; aos_string_t object; aos_list_t buffer; aos_buf_t *content = NULL; aos_table_t *headers = NULL; aos_table_t *resp_headers = NULL; aos_status_t *resp_status = NULL; aos_str_set(&bucket, bucket_name); aos_str_set(&object, object_name); aos_list_init(&buffer); content = aos_buf_pack(oss_client_options->pool, object_content, strlen(object_content)); aos_list_add_tail(&content->node, &buffer); /* 上傳檔案。*/ resp_status = oss_put_object_from_buffer(oss_client_options, &bucket, &object, &buffer, headers, &resp_headers); /* 判斷上傳是否成功。*/ if (aos_status_is_ok(resp_status)) { printf("put object from buffer succeeded\n"); } else { printf("put object from buffer failed\n"); } /* 釋放記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/ aos_pool_destroy(pool); /* 釋放之前分配的全域資源。*/ aos_http_io_deinitialize(); return 0; }
重新命名目錄
目錄重新命名並非單一的原子操作,無論使用何種工具,其底層原理都是一個複合工作流程:
複製:將原目錄下的所有檔案遞迴地複製到一個新的目標目錄下。
刪除:確認複製成功後,將原目錄及其下的所有檔案徹底刪除。
由於重新命名需要逐一複製和刪除目錄下的所有檔案,該操作對大目錄將非常耗時,並會產生大量的API調用和流量費用,請務必謹慎評估。
已開啟階層命名空間,要重新命名目錄(檔案夾),您可以直接對目錄進行重新命名操作
控制台
登入OSS管理主控台。
單擊Bucket 列表,然後單擊目標Bucket名稱。
在左側導覽列,選擇文件管理>檔案清單。
重新命名或移動目錄。
您可以在ossutil的rm命令樣本中通過prefix選項指定待刪除目錄名稱的方式刪除指定目錄。具體操作,請參見rm(刪除)。
情境
操作
重新命名目錄
將滑鼠指標懸停在目標目錄上,然後單擊表徵圖
,對目錄進行重新命名。重新命名時,目錄名稱不能以正斜線/開頭。移動目錄
移動目錄與重新命名目錄操作類似,區別在於填寫的目錄名稱必須以正斜線(/)開頭。根據如下情境填寫符合要求的目標目錄。
如果您希望將父目錄destdir下的子目錄subdir移動至父目錄destfolder下,則重新命名時目錄填寫為/destfolder/subdir。
如果您希望將父目錄destdir下的子目錄subdir移動至Bucket根目錄,則重新命名時目錄填寫為/subdir。
SDK
僅支援通過Java SDK重新命名目錄,Java SDK要求3.12.0及以上版本。
import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.*; public class Demo { public static void main(String[] args) throws Exception { // yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 String endPoint = "yourEndpoint"; // 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。運行本程式碼範例之前,請先配置環境變數。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫Bucket名稱,例如examplebucket。 String bucketName = "examplebucket"; // 填寫來源目錄絕對路徑。目錄絕對路徑中不能包含Bucket名稱。 String sourceDir = "exampledir"; // 填寫與來源目錄處於同一Bucket中的目標目錄絕對路徑。目錄絕對路徑中不能包含Bucket名稱。 String destinationDir = "newexampledir"; // 建立OSSClient執行個體。 OSS ossClient = new OSSClientBuilder().build(endPoint, credentialsProvider); try { // 將儲存空間中的來源目錄絕對路徑重新命名為目標目錄絕對路徑。 RenameObjectRequest renameObjectRequest = new RenameObjectRequest(bucketName, sourceDir, destinationDir); ossClient.renameObject(renameObjectRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }API
如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見Rename。
未開啟階層命名空間,要重新命名目錄(檔案夾),您需要列舉出屬於該目錄的所有Object,將其複製到新的首碼下,然後刪除舊的Object。
說明如果要複製的檔案數量較多,您可以使用線上遷移服務進行批量複製。詳情請參見阿里雲OSS之間遷移教程。
ossutil
使用ossutil時,需要手動執行複製和刪除兩個核心步驟來完成重新命名。
複製檔案
使用cp(拷貝檔案)命令並附帶--recursive (-r)選項,將儲存空間examplebucket中old-dir/下的所有內容複寫到new-dir/。ossutil cp oss://examplebucket/old-dir/ oss://examplebucket/new-dir/ -r(可選)驗證
使用ls(列舉帳號層級下的資源)命令檢查新目錄,確保所有檔案已成功複製。ossutil ls oss://examplebucket/new-dir/刪除原目錄
確認複製無誤後,使用rm(刪除)命令並附帶--recursive (-r)選項,刪除原目錄old-dir/。警告此操作將永久刪除
old-dir/目錄及其下的所有檔案,刪除後無法恢複,請務必謹慎操作。ossutil rm oss://examplebucket/old-dir/ -r
SDK
如上所述,通過SDK重新命名目錄需要組合多個API完成。具體實現可分別參考以下核心操作的SDK文檔:
API
通過API重新命名目錄,需要組合以下API調用完成:
刪除目錄
刪除目錄會同步刪除目錄下包含的子目錄以及所有檔案,請謹慎操作。
控制台
登入OSS管理主控台。
進入目標Bucket的檔案管理 > 檔案清單頁面。
選擇要刪除的目錄,單擊操作列的徹底刪除。
在彈出的對話方塊中單擊確定。
重要刪除目錄及檔案期間,請勿重新整理或關閉工作清單,否則會導致任務中斷。
ossutil
以下樣本展示了如何刪除儲存空間examplebucket下的目錄test/。
ossutil rm oss://examplebucket/test/ -r更多用法見rm(刪除)。
SDK
您可以通過指定Prefix的方式刪除目錄及目錄下的所有檔案。例如,您希望刪除儲存空間examplebucket下目錄log及該目錄下的所有檔案,請將範例程式碼中的Prefix參數指定為log/。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。運行本程式碼範例之前,請先配置環境變數。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫目錄絕對路徑。目錄絕對路徑中不能包含Bucket名稱。
String directoryName = "exampledir";
// 填寫待刪除目錄的完整路徑,完整路徑中不包含Bucket名稱。
final String prefix = "log/";
// 建立OSSClient執行個體。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 方法1:通過deleteDirectory遞迴刪除方式刪除目錄。使用該方法刪除目錄前,需要開啟階層命名空間。
DeleteDirectoryRequest deleteDirectoryRequest = new DeleteDirectoryRequest(bucketName, directoryName);
deleteDirectoryRequest.setDeleteRecursive(true);
DeleteDirectoryResult deleteDirectoryResult = ossClient.deleteDirectory(deleteDirectoryRequest);
// 查看刪除結果。
// 一次支援刪除的目錄和檔案的總和為100個,當一次未刪除完時,服務端會返回nextDeleteToken,此時您可以使用nextDeleteToken繼續刪除後面的資料。
// nextDeleteToken用於服務端找到下一次刪除的起點。
String nextDeleteToken = deleteDirectoryResult.getNextDeleteToken();
System.out.println("delete next token:" + nextDeleteToken);
// 刪除的目錄絕對路徑。
System.out.println("delete dir name :" + deleteDirectoryResult.getDirectoryName());
// 本次刪除的檔案和目錄的總數量。
System.out.println("delete number:" + deleteDirectoryResult.getDeleteNumber());
// 方法2:使用遍曆listObjects的結果刪除目錄及目錄下的所有檔案。
String nextMarker = null;
ObjectListing objectListing = null;
do {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName)
.withPrefix(prefix)
.withMarker(nextMarker);
objectListing = ossClient.listObjects(listObjectsRequest);
if (objectListing.getObjectSummaries().size() > 0) {
List<String> keys = new ArrayList<String>();
for (OSSObjectSummary s : objectListing.getObjectSummaries()) {
System.out.println("key name: " + s.getKey());
keys.add(s.getKey());
}
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(keys).withEncodingType("url");
DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(deleteObjectsRequest);
List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
try {
for(String obj : deletedObjects) {
String deleteObj = URLDecoder.decode(obj, "UTF-8");
System.out.println(deleteObj);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
nextMarker = objectListing.getNextMarker();
} while (objectListing.isTruncated());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\OssClient;
use OSS\Core\OssException;
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱。
$bucket = "examplebucket";
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
$option = array(
OssClient::OSS_MARKER => null,
// 填寫待刪除目錄的完整路徑,完整路徑中不包含Bucket名稱。
OssClient::OSS_PREFIX => "log/",
OssClient::OSS_DELIMITER=>'',
);
$bool = true;
while ($bool){
$result = $ossClient->listObjects($bucket,$option);
$objects = array();
if(count($result->getObjectList()) > 0){
foreach ($result->getObjectList() as $key => $info){
printf("key name:".$info->getKey().PHP_EOL);
$objects[] = $info->getKey();
}
// 刪除目錄及目錄下的所有檔案。
$delObjects = $ossClient->deleteObjects($bucket, $objects);
foreach ($delObjects as $info){
$obj = strval($info);
printf("Delete ".$obj." : Success" . PHP_EOL);
}
}
if($result->getIsTruncated() === 'true'){
$option[OssClient::OSS_MARKER] = $result->getNextMarker();
}else{
$bool = false;
}
}
printf("Delete Objects : OK" . PHP_EOL);
} catch (OssException $e) {
printf("Delete Objects : Failed" . PHP_EOL);
printf($e->getMessage() . PHP_EOL);
return;
}const OSS = require('ali-oss');
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: 'yourregion',
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
// 填寫儲存空間名稱。
bucket: 'yourbucketname'
});
// 處理請求失敗的情況,防止promise.all中斷,並返回失敗原因和失敗檔案名稱。
async function handleDel(name, options) {
try {
await client.delete(name);
} catch (error) {
error.failObjectName = name;
return error;
}
}
// 刪除多個檔案。
async function deletePrefix(prefix) {
const list = await client.list({
prefix: prefix,
});
list.objects = list.objects || [];
const result = await Promise.all(list.objects.map((v) => handleDel(v.name)));
console.log(result);
}
// 刪除目錄及目錄下的所有檔案。
deletePrefix('log/')# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
prefix = "exampledir/"
# 刪除目錄及目錄下的所有檔案。
for obj in oss2.ObjectIterator(bucket, prefix=prefix):
bucket.delete_object(obj.key)package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 建立OSSClient執行個體。
// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填寫Bucket名稱。
bucket, err := client.Bucket("examplebucket")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
marker := oss.Marker("")
// 填寫待刪除目錄的完整路徑,完整路徑中不包含Bucket名稱。
prefix := oss.Prefix("log/")
count := 0
for {
lor, err := bucket.ListObjects(marker, prefix)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
objects := []string{}
for _, object := range lor.Objects {
objects = append(objects, object.Key)
}
// 刪除目錄及目錄下的所有檔案。
// 將oss.DeleteObjectsQuiet設定為true,表示不返回刪除結果。
delRes, err := bucket.DeleteObjects(objects, oss.DeleteObjectsQuiet(true))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
if len(delRes.DeletedObjects) > 0 {
fmt.Println("these objects deleted failure,", delRes.DeletedObjects)
os.Exit(-1)
}
count += len(objects)
prefix = oss.Prefix(lor.Prefix)
marker = oss.Marker(lor.NextMarker)
if !lor.IsTruncated {
break
}
}
fmt.Printf("success,total delete object count:%d\n", count)
}#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* 初始化OSS帳號資訊。*/
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
std::string Endpoint = "yourEndpoint";
/* 填寫Bucket名稱。*/
std::string BucketName = "examplebucket";
/* 填寫待刪除目錄的完整路徑,完整路徑中不包含Bucket名稱。*/
std::string keyPrefix = "log/";
/* 初始化網路等資源。*/
InitializeSdk();
ClientConfiguration conf;
/* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
std::string nextMarker = "";
bool isTruncated = false;
do {
ListObjectsRequest request(BucketName);
request.setPrefix(keyPrefix);
request.setMarker(nextMarker);
auto outcome = client.ListObjects(request);
if (!outcome.isSuccess()) {
/* 異常處理。*/
std::cout << "ListObjects fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
break;
}
for (const auto& object : outcome.result().ObjectSummarys()) {
DeleteObjectRequest request(BucketName, object.Key());
/* 刪除目錄及目錄下的所有檔案。*/
auto delResult = client.DeleteObject(request);
}
nextMarker = outcome.result().NextMarker();
isTruncated = outcome.result().IsTruncated();
} while (isTruncated);
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}API
如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見DeleteObject。
查詢目錄的檔案數量及大小
方式一:通過列舉檔案的方式臨時查詢
該方式適用於指定目錄下檔案數量較少(如一萬以內),且以臨時性查詢為主的情境。
在目標Bucket的左側導覽列, 選擇。
單擊目標目錄右側的統計。

方式二:通過儲存空間清單的方式定期查詢
該方式適用於指定目錄的檔案數量較大(百億級)且需要定期查詢的情境。
在目標Bucket的左側導覽列, 選擇。
單擊建立清單,在設定清單報告規則面板,選擇儲存清單 Bucket、清單內容選擇Object大小、按首碼匹配輸入需要查詢的目錄名稱(例如random_files/),其他參數保留預設配置。

查看清單結果。
在檔案清單頁面的
/儲存清單Bucket/清單id/data/路徑下找到產生的清單結果檔案。將清單結果檔案下載到本地,查看該目錄下的檔案數量和大小。
清單結果檔案中A列資料代表Bucket名稱,B列資料是該目錄及目錄下的所有檔案清單,C列資料是目錄和目錄下的檔案大小。

更多儲存空間清單資訊,請參見儲存空間清單。
方式三:通過標量檢索的方式結合多種條件查詢
該方式適用於需要對指定目錄下的檔案數量和大小進行准即時統計,並且支援靈活條件式篩選(如按首碼、時間、檔案類型等)的情境。
在目標Bucket的左側導覽列, 選擇
在資料索引頁面,單擊立即開啟,然後選擇標量檢索,單擊確認開啟。
說明開啟標量檢索需要等待一定的時間,具體等待時間長度取決於Bucket中Object的數量。
將檔案名稱設定為首碼匹配,並輸入首碼匹配:
random_files/,其他參數保留預設設定。
設定輸出方式。
對象排序方式選擇按照預設排序排列。
資料彙總選擇按照檔案大小的求和輸出。

單擊立即查詢,可以看到最終統計到的random_files/目錄下所有檔案和總大小結果。

更多標量檢索資訊,請參見標量檢索。
應用於生產
許可權管理
OSS的許可權管理基於檔案首碼匹配,而不是目錄檔案本身。
例如,要授予使用者唯讀訪問 logs/ 目錄下所有檔案的許可權。
錯誤做法:嘗試為
logs/這個0位元組對象設定許可權。正確做法:建立RAM策略,將
Resource欄位設定為acs:oss:*:*:your-bucket-name/logs/*。該策略會匹配所有以logs/為首碼的對象,無論logs/目錄的0位元組預留位置對象是否存在。
效能最佳化
目錄層級深度:避免過深的嵌套結構(如
a/b/c/d/.../file.log),因為列舉操作的過濾邏輯會影響效能。大規模重新命名:重新命名包含大量檔案的目錄會產生大量API調用和流量費用,設計系統時應盡量避免。