全部產品
Search
文件中心

Object Storage Service:管理OSS目錄

更新時間:Jun 19, 2024

與傳統檔案系統中的層級結構不同,OSS內部使用扁平結構儲存資料。即所有資料均以對象(Object)的形式儲存在儲存空間(Bucket)中。為方便管理,OSS控制台將所有以正斜線(/)結尾的對象顯示為目錄,實作類別似於目錄的準系統。您可以通過目錄的層次來組織檔案,實現分組並簡化許可權管理。

工作原理

OSS通過建立大小為0位元組的對象來類比目錄的概念,以便實作類別似目錄的管理和展示。當您在OSS中建立目錄時,OSS會使用您提供的目錄名稱來建立一個大小為0位元組的對象。例如,如果您在儲存空間中建立一個名為log的目錄,OSS將使用log/作為對象名稱來建立一個大小為0位元組的對象。

目錄樣本

OSS將以正斜線(/)結尾的對象視為目錄。例如目標儲存空間examplebucket下的目錄及檔案結構如下所示:

examplebucket
    └── log/
       ├── date1.txt
       ├── date2.txt
       ├── date3.txt
    └── destfolder/
       └── 2021/
          ├── photo.jpg

以上目錄結構示意圖表明:

  • 以log為首碼的檔案共有三個,分別為log/date1.txtlog/date2.txtlog/date3.txt。控制台會顯示名稱為log的目錄,如果您在控制台中開啟該目錄,將看到三個檔案,分別為date1.txtdate2.txtdate3.txt

  • 以destfolder為首碼的檔案為destfolder/2021/photo.jpg。控制台將顯示名稱為destfolder的目錄,其中包含子目錄2021,子目錄下包含檔案photo.jpg

授權目錄

例如,您希望授予第三方使用者對上述樣本的目標儲存空間examplebucket下不同目錄或者檔案有不同的存取權限,您可以通過以下方式來實現:

  • log目錄的三個檔案log/date1.txtlog/date2.txtlog/date3.txt,分別用於儲存某使用者近三天訪問OSS的日誌。經發現近三天出現了訪問速度下降、上傳檔案失敗的情況,該使用者希望相關技術支援人員可以查看log目錄下的所有檔案,以協助排查並解決問題。此時,您可以通過Bucket Policy授權使用者訪問指定資源。具體步驟,請參見配置Bucket Policy

  • destfolder/2021/photo.jpg檔案為公司全員2021年外出春遊合照,希望公司全員都可以查看。此時,您可以將檔案讀寫權限ACL設定為公用讀取。具體步驟,請參見設定Object ACL

建立目錄

您可以通過以下多種方式類比建立目錄。

說明

除了類比建立目錄,您也可以在上傳檔案時通過指定檔案的首碼來類比自動建立目錄。例如,上傳的檔案路徑為exampledir/demo.txt,則OSS會自動建立exampledir目錄。

使用OSS控制台

  1. 登入OSS管理主控台

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

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

  4. 檔案清單頁面,單擊新建目錄

  5. 新建目錄面板,輸入目錄名

    目錄命名規範如下:

    • 不允許使用Emoji,請使用符合要求的UTF-8字元。
    • 正斜線/用於分割路徑,可快速建立子目錄,但不要以正斜線/或反斜線\開頭,不要出現連續的正斜線/
    • 不允許出現名為..的子目錄。
    • 總長度控制在1~254個字元。
  6. 單擊確定

使用圖形化管理工具ossbrowser

ossbrowser支援Object層級的操作與控制台支援的操作類似,請按照ossbrowser介面指引完成建立目錄的操作。關於如何使用ossbrowser,請參見快速使用ossbrowser

使用阿里雲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/', '')    
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)
    }

    // 填寫儲存空間名稱,例如examplebucket。
    bucket, err := client.Bucket("examplebucket")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 填寫目錄名稱,目錄需以正斜線結尾。
    err = bucket.PutObject("exampledir/", bytes.NewReader([]byte("")))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}           
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;
}

使用命令列工具ossutil

關於使用ossutil建立目錄的具體操作,請參見mkdir(建立目錄)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見PutObjectCreateDirectory

重新命名目錄

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

使用OSS控制台

  1. 登入OSS管理主控台

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

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

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

    情境

    操作

    重新命名目錄

    將滑鼠指標懸停在目標目錄上,然後單擊表徵圖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();
            }
        }
    }
}

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見Rename

未開啟階層命名空間,要重新命名目錄(檔案夾),您需要列舉出屬於該目錄的所有Object,將其複製到新的首碼下,然後刪除舊的Object。

說明

如果要複製的檔案數量較多,您可以使用線上遷移服務進行批量複製。詳情請參見阿里雲OSS之間遷移教程

使用ossbrowser

  1. 安裝並登入ossbrowser

  2. 選中目錄,然後在頂部功能表列,選擇更多 > 重新命名

    ossbrowser重新命名目錄.png

  3. 重新命名對話方塊中,設定新的目錄名,然後單擊確定

使用阿里雲SDK

關於使用SDK重新命名目錄涉及的範例程式碼,請參見列舉檔案拷貝檔案刪除檔案

使用命令列工具ossutil

關於使用ossutil重新命名目錄涉及的命令,請參見ls(列舉帳號層級下的資源)cp(拷貝檔案)rm(刪除)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見ListObjectsV2(GetBucketV2)(或GetBucket (ListObjects))、CopyObjectDeleteObject

刪除目錄

當您不希望保留該目錄時,也可以通過以下多種方式刪除目錄。

警告

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

使用OSS控制台

  1. 登入OSS管理主控台

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

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

  4. 檔案清單頁簽,根據您的需求刪除指定目錄。

    重要

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

    • 在已開啟階層命名空間的Bucket中刪除

      單擊目標目錄右側的刪除,然後在彈出的對話方塊單擊確定

      此時,目標目錄及其包含的檔案會被徹底刪除。

    • 在未開啟階層命名空間的Bucket中刪除

      • 在Bucket未開啟階層命名空間,且未開啟版本控制的情況下,目錄及檔案的刪除行為與已開啟階層命名空間的Bucket中的刪除行為一致。

      • 在Bucket未開啟階層命名空間,且已開啟版本控制的情況下,對目錄及檔案進行刪除時,會有以下兩種情況:

        • 將目錄轉為歷史版本

          1. 在檔案清單右上方,將歷史版本設定為隱藏

          2. 單擊目標目錄右側的刪除,然後在彈出的對話方塊單擊確定

            此時,刪除的目錄及檔案會被轉為歷史版本,您可以在需要時對目錄和檔案進行恢複。恢複歷史版本檔案的具體操作,請參見恢複歷史版本Object

        • 將目錄徹底刪除

          1. 在檔案清單右上方,將歷史版本設定為顯示

          2. 單擊目標目錄右側的徹底刪除,然後在彈出的對話方塊單擊確定

            此時,目錄及其目錄下的檔案會被徹底刪除。

    • Bucket未開啟版本控制

      單擊目標目錄右側的徹底刪除,然後在彈出的對話方塊單擊確定

      此時,目錄及其目錄下的檔案會被徹底刪除。

    • Bucket已開啟或暫停版本控制

      • 將目錄轉為歷史版本

        1. 在檔案清單右上方,將歷史版本設定為隱藏

        2. 單擊目標目錄右側的刪除,然後在彈出的對話方塊單擊確定

          此時,刪除的目錄及目錄下的檔案會被轉為歷史版本,您可以在需要時對目錄和檔案進行恢複。恢複歷史版本檔案的具體操作,請參見恢複歷史版本Object

      • 將目錄徹底刪除

        1. 在檔案清單右上方,將歷史版本設定為顯示

        2. 單擊目標目錄右側的徹底刪除,然後在彈出的對話方塊單擊確定

          此時,目錄及其目錄下的檔案會被徹底刪除。

  5. 在彈出的工作清單面板查看刪除進度。

    刪除任務進行期間,您可以進行以下操作:

    • 移除已完成:單擊可移除列表中已完成的刪除任務。

    • 全部暫停:單擊可暫停進行中中的刪除任務。任務暫停期間,您可以進行以下操作:

      • 單擊目標任務右側的開始,重新開始任務。

      • 單擊目標任務右側的移除,移除該任務。任務移除後,未刪除的檔案將繼續保留。

    • 全部開始:單擊可開始全部暫停中的刪除任務。

使用圖形化管理工具ossbrowser

ossbrowser支援Object層級的操作與控制台支援的操作類似,請按照ossbrowser介面指引完成刪除目錄的操作。關於如何使用ossbrowser,請參見快速使用ossbrowser

使用阿里雲SDK

以下僅列舉常見SDK的刪除目錄的程式碼範例。關於其他SDK的刪除目錄的程式碼範例,請參見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;
}

使用命令列工具ossutil

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

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見DeleteObjectDeleteDirectory

擷取目錄大小

您可以通過以下多種方式擷取目錄下的檔案總大小。

使用OSS控制台

  1. 登入OSS管理主控台

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

  3. 檔案清單頁面,單擊目標目錄右側的檔案大小重新整理表徵圖。

    filesize.jpg

    目標目錄下的檔案總大小顯示如下:

    filesize2.jpg

使用阿里雲SDK

以下僅列舉常見SDK的擷取目錄大小的程式碼範例。關於其他SDK的擷取目錄大小的程式碼範例,請參見SDK簡介

Java

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
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";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 指定首碼,例如exampledir/object。如果您希望遍曆主目錄下的檔案夾,則將此值置空。
        String keyPrefix = "exampledir/object";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            ObjectListing objectListing = null;
            do {
                // 預設情況下,每次列舉100個檔案或目錄。
                ListObjectsRequest request = new ListObjectsRequest(bucketName).withDelimiter("/").withPrefix(keyPrefix);
                if (objectListing != null) {
                    request.setMarker(objectListing.getNextMarker());
                }
                objectListing = ossClient.listObjects(request);
                List<String> folders = objectListing.getCommonPrefixes();
                for (String folder : folders) {
                    System.out.println(folder + " : " + (calculateFolderLength(ossClient, bucketName, folder) / 1024) + "KB");
                }
                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                for (OSSObjectSummary s : sums) {
                    System.out.println(s.getKey() + " : " + (s.getSize() / 1024) + "KB");
                }
            } 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();
            }
        }
    }

    // 擷取某個儲存空間下指定目錄(檔案夾)下的檔案大小。
    private static long calculateFolderLength(OSS ossClient, String bucketName, String folder) {
        long size = 0L;
        ObjectListing objectListing = null;
        do {
            // MaxKey預設值為100,最大值為1000。
            ListObjectsRequest request = new ListObjectsRequest(bucketName).withPrefix(folder).withMaxKeys(1000);
            if (objectListing != null) {
                request.setMarker(objectListing.getNextMarker());
            }
            objectListing = ossClient.listObjects(request);
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            for (OSSObjectSummary s : sums) {
                size += s.getSize();
            }
        } while (objectListing.isTruncated());
        return size;
    }
}

PHP

<?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';
}
require_once __DIR__ . '/Common.php';
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;

// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填寫Bucket名稱,例如examplebucket。
$bucket= "examplebucket";

$config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
// 指定目錄名稱為fun/。
$prefix = 'fun/';
$delimiter = '';
$nextMarker = '';
$maxkeys = 1000;
$options = array(
    'delimiter' => $delimiter,
    'prefix' => $prefix,
    'max-keys' => $maxkeys,
    'marker' => $nextMarker,
);
$bool = true;
$size = 0;
while ($bool){
    $result = $ossClient->listObjects($bucket,$options);
    foreach ($result->getObjectList() as $objInfo){
        printf("object name".$objInfo->getKey().":" . ($objInfo->getSize() / 1024) . "KB".PHP_EOL);
        $size+=$objInfo->getSize();
    }
    if($result->getIsTruncated() === 'true'){
        $options['marker'] = $result->getNextMarker();
    }else{
        $bool = false;
    }
}
printf($prefix.":" . ($size / 1024) . "KB".PHP_EOL);

Python

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

def CalculateFolderLength(bucket, folder):
    length = 0
    for obj in oss2.ObjectIterator(bucket, prefix=folder):
        length += obj.size
    return length
# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

for obj in oss2.ObjectIterator(bucket, delimiter='/'):
    if obj.is_prefix():  # 判斷obj為檔案夾。
        length = CalculateFolderLength(bucket, obj.key)
        print('directory: ' + obj.key + '  length:' + str(length) + "Byte.")
    else: # 判斷obj為檔案。
        print('file:' + obj.key + '  length:' + str(obj.size) + "Byte.")

Go

package main
import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)
func HandleError(err error) {
    fmt.Println("Error:", err)
    os.Exit(-1)
}
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, err := client.Bucket("yourBucketName")
    if err != nil {
        HandleError(err)
        os.Exit(-1)
    }
    // 擷取指定目錄下的檔案大小。
    prefix := "test/"
    marker := ""
    for {
        lsRes, err := bucket.ListObjects(oss.Prefix(prefix),oss.Marker(marker))
        if err != nil {
           HandleError(err)
           os.Exit(-1)
        }
        for _,object := range lsRes.Objects{
           fmt.Println("Objects",object.Key, "length",object.Size ,"Byte.")
        }
        if lsRes.IsTruncated {
           marker = lsRes.NextMarker
           prefix = lsRes.Prefix
        }else{
           break
        }
     }
}

使用命令列工具ossutil

關於使用ossutil擷取指定目錄下的檔案大小的具體步驟,請參見查詢指定目錄下所有目前的版本Object的大小

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見GetBucket (ListObjects)