全部產品
Search
文件中心

Object Storage Service:管理OSS目錄

更新時間:Oct 20, 2025

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位元組檔案,以此作為空白目錄的預留位置。

    控制台

    1. OSS管理主控台,進入目標Bucket的檔案管理 > 檔案清單頁面。

    2. 單擊新建目錄

    3. 輸入目錄名,然後單擊確定

      目錄命名規範如下:

      • 不允許使用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;
    }

重新命名目錄

目錄重新命名並非單一的原子操作,無論使用何種工具,其底層原理都是一個複合工作流程:

  1. 複製:將原目錄下的所有檔案遞迴地複製到一個新的目標目錄下。

  2. 刪除:確認複製成功後,將原目錄及其下的所有檔案徹底刪除。

重要

由於重新命名需要逐一複製和刪除目錄下的所有檔案,該操作對大目錄將非常耗時,並會產生大量的API調用和流量費用,請務必謹慎評估。

  • 已開啟階層命名空間,要重新命名目錄(檔案夾),您可以直接對目錄進行重新命名操作

    控制台

    1. 登入OSS管理主控台

    2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

    3. 在左側導覽列,選擇文件管理>檔案清單

    4. 重新命名或移動目錄。

      您可以在ossutil的rm命令樣本中通過prefix選項指定待刪除目錄名稱的方式刪除指定目錄。具體操作,請參見rm(刪除)

      情境

      操作

      重新命名目錄

      將滑鼠指標懸停在目標目錄上,然後單擊表徵圖edit,對目錄進行重新命名。重新命名時,目錄名稱不能以正斜線/開頭。

      移動目錄

      移動目錄與重新命名目錄操作類似,區別在於填寫的目錄名稱必須以正斜線(/)開頭。根據如下情境填寫符合要求的目標目錄。

      • 如果您希望將父目錄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時,需要手動執行複製刪除兩個核心步驟來完成重新命名。

    1. 複製檔案
      使用cp(拷貝檔案)命令並附帶--recursive (-r) 選項,將儲存空間examplebucketold-dir/下的所有內容複寫到new-dir/

      ossutil cp oss://examplebucket/old-dir/ oss://examplebucket/new-dir/ -r
    2. (可選)驗證
      使用ls(列舉帳號層級下的資源)命令檢查新目錄,確保所有檔案已成功複製。

      ossutil ls oss://examplebucket/new-dir/
    3. 刪除原目錄
      確認複製無誤後,使用rm(刪除)命令並附帶--recursive (-r) 選項,刪除原目錄old-dir/

      警告

      此操作將永久刪除old-dir/目錄及其下的所有檔案,刪除後無法恢複,請務必謹慎操作。

      ossutil rm oss://examplebucket/old-dir/ -r

    SDK

    如上所述,通過SDK重新命名目錄需要組合多個API完成。具體實現可分別參考以下核心操作的SDK文檔:

    API

    通過API重新命名目錄,需要組合以下API調用完成:

刪除目錄

警告

刪除目錄會同步刪除目錄下包含的子目錄以及所有檔案,請謹慎操作。

控制台

  1. 登入OSS管理主控台

  2. 進入目標Bucket的檔案管理 > 檔案清單頁面。

  3. 選擇要刪除的目錄,單擊操作列的徹底刪除

  4. 在彈出的對話方塊中單擊確定

    重要

    刪除目錄及檔案期間,請勿重新整理或關閉工作清單,否則會導致任務中斷。

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

查詢目錄的檔案數量及大小

方式一:通過列舉檔案的方式臨時查詢

該方式適用於指定目錄下檔案數量較少(如一萬以內),且以臨時性查詢為主的情境。

  1. 在目標Bucket的左側導覽列, 選擇文件管理 > 檔案清單

  2. 單擊目標目錄右側的統計

    filesize.jpg

方式二:通過儲存空間清單的方式定期查詢

該方式適用於指定目錄的檔案數量較大(百億級)且需要定期查詢的情境。

  1. 在目標Bucket的左側導覽列, 選擇資料管理 > Bucket 清單

  2. 單擊建立清單,在設定清單報告規則面板,選擇儲存清單 Bucket、清單內容選擇Object大小、按首碼匹配輸入需要查詢的目錄名稱(例如random_files/),其他參數保留預設配置。

    screenshot_2025-07-04_18-14-09

  3. 查看清單結果。

    1. 檔案清單頁面的/儲存清單Bucket/清單id/data/路徑下找到產生的清單結果檔案。

    2. 將清單結果檔案下載到本地,查看該目錄下的檔案數量和大小。

      清單結果檔案中A列資料代表Bucket名稱,B列資料是該目錄及目錄下的所有檔案清單,C列資料是目錄和目錄下的檔案大小。

      screenshot_2025-07-04_18-28-44

更多儲存空間清單資訊,請參見儲存空間清單

方式三:通過標量檢索的方式結合多種條件查詢

該方式適用於需要對指定目錄下的檔案數量和大小進行准即時統計,並且支援靈活條件式篩選(如按首碼、時間、檔案類型等)的情境。

  1. 在目標Bucket的左側導覽列, 選擇文件管理 > 數據索引

  2. 資料索引頁面,單擊立即開啟,然後選擇標量檢索,單擊確認開啟

    說明

    開啟標量檢索需要等待一定的時間,具體等待時間長度取決於Bucket中Object的數量。

  3. 檔案名稱設定為首碼匹配,並輸入首碼匹配:random_files/,其他參數保留預設設定。

    image

  4. 設定輸出方式

    • 對象排序方式選擇按照預設排序排列。

    • 資料彙總選擇按照檔案大小求和輸出。

      image

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

    image

更多標量檢索資訊,請參見標量檢索

應用於生產

許可權管理

OSS的許可權管理基於檔案首碼匹配,而不是目錄檔案本身。

例如,要授予使用者唯讀訪問 logs/ 目錄下所有檔案的許可權。

  • 錯誤做法:嘗試為 logs/ 這個0位元組對象設定許可權。

  • 正確做法:建立RAM策略,將Resource欄位設定為 acs:oss:*:*:your-bucket-name/logs/*。該策略會匹配所有以 logs/ 為首碼的對象,無論 logs/ 目錄的0位元組預留位置對象是否存在。

效能最佳化

  • 目錄層級深度:避免過深的嵌套結構(如 a/b/c/d/.../file.log),因為列舉操作的過濾邏輯會影響效能。

  • 大規模重新命名:重新命名包含大量檔案的目錄會產生大量API調用和流量費用,設計系統時應盡量避免。