すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:OSS ディレクトリの管理

最終更新日:Oct 22, 2025

フラットな構造では困難な場合がある多数のオブジェクトの編成と管理を簡素化するために、Object Storage Service (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

ディレクトリの作成

ディレクトリは 2 つの方法で作成できます:

  • オブジェクトのアップロード時の自動作成: パスを含む名前のオブジェクトをアップロードすると、OSS は対応するディレクトリを自動的に作成します。

  • 空のディレクトリの手動作成: この操作では、名前が / で終わる 0 バイトのオブジェクトが作成され、空のディレクトリのプレースホルダーとして機能します。

    コンソール

    1. OSS コンソールにログインし、ターゲットバケットの [オブジェクト管理] > [オブジェクト] ページに移動します。

    2. ディレクトリの作成 をクリックします。

    3. [ディレクトリ名] を入力し、[OK] をクリックします。

      ディレクトリには、次の命名ルールに従ってください:

      • ディレクトリ名は UTF-8 でエンコードする必要があり、絵文字を含めることはできません。

      • スラッシュ (/) は、サブディレクトリを示すためにディレクトリ名で使用されます。ディレクトリ名にスラッシュ (/) を使用して、ネストされたディレクトリ構造を作成します。ディレクトリ名はスラッシュ (/) またはバックスラッシュ (\) で始めることはできません。ディレクトリ名に連続するスラッシュ (//) を含めることはできません。

      • サブディレクトリ名に 2 つの連続するピリオド (..) を使用することはできません。

      • ディレクトリ名の長さは 1~254 文字である必要があります。

    ossutil

    次の例は、examplebucket バケットに dir/ という名前のディレクトリを作成する方法を示しています。

    ossutil mkdir oss://examplebucket/dir

    詳細については、「mkdir (ディレクトリの作成)」をご参照ください。

    SDK

    次のコードは、一般的な SDK を使用してディレクトリを作成する方法の例を示しています。他の SDK を使用してディレクトリを作成する方法の詳細については、「OSS 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 {
            // エンドポイントの例として、中国 (杭州) リージョンが使用されています。実際のリージョンに基づいてエンドポイントを指定してください。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // アクセス資格情報をコードにハードコーディングしないでください。資格情報が漏洩すると、すべてのリソースのセキュリティが損なわれる可能性があります。この例では、環境変数から資格情報を取得します。コードを実行する前に環境変数を設定してください。
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // bucketName をバケットの名前に設定します (例: examplebucket)。
            String bucketName = "examplebucket";
            // dirName を方法 1 で作成したディレクトリの名前に設定します。
            String dirName = "exampledir/";
            // dirName2 を方法 2 で作成したディレクトリの名前に設定します。
            String dirName2 = "exampledir1/";
    
            // OSSClient インスタンスを作成します。
            OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
    
            try {
                // 方法 1: createDirectory 操作を呼び出してディレクトリを作成します。このメソッドを使用する前に、階層的な名前空間を有効にする必要があります。
                ossClient.createDirectory(bucketName, dirName);
    
                // 方法 2: 空の文字列をアップロードしてディレクトリを作成します。
                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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
    $endpoint = "yourEndpoint";
    // bucket をバケットの名前に設定します (例: examplebucket)。
    $bucket= "examplebucket";
    // object をディレクトリ名に設定します。名前はスラッシュ (/) で終わる必要があります。
    $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");
    
    // オブジェクトをアップロードするときに、アクセス権限を 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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを 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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
    # バケット名を設定します。
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
    
    # ディレクトリ名を設定します。名前はスラッシュ (/) で終わる必要があります。
    bucket.put_object('exampledir/', '')    
    using System.Text;
    using Aliyun.OSS;
    
    // yourEndpoint をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを 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");
    // bucketName をバケットの名前に設定します (例: examplebucket)。
    var bucketName = "examplebucket";
    // objectName をディレクトリ名に設定します。名前はスラッシュ (/) で終わる必要があります。
    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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 */
    const char *endpoint = "yourEndpoint";
    
    /* bucket_name をバケットの名前に設定します (例: examplebucket)。 */
    const char *bucket_name = "examplebucket";
    /* object_name をディレクトリ名に設定します。名前はスラッシュ (/) で終わる必要があります。 */
    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 は CNAME が使用されないことを示します。 */
        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;
        /* メモリプールを作成します。2 番目のパラメーターは NULL で、メモリプールが別のメモリプールから継承しないことを示します。 */
        aos_pool_create(&pool, NULL);
        /* オプションを作成して初期化します。このパラメーターには、endpoint、access_key_id、access_key_secret、is_cname、curl などのグローバル構成情報が含まれます。 */
        oss_request_options_t *oss_client_options;
        /* メモリプール内のオプションにメモリを割り当てます。 */
        oss_client_options = oss_request_options_create(pool);
        /* クライアントオプション 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. 左側のナビゲーションウィンドウで、バケット をクリックします。バケットページで、目的のバケットを見つけてクリックします。

    3. 左側のナビゲーションツリーで、オブジェクト管理 > オブジェクト を選択します。

    4. ディレクトリの名前を変更するか、移動します。

      ossutil rm コマンドの [prefix] オプションで名前を指定して、ディレクトリを削除します。

      ユースケース

      アクション

      ディレクトリの名前を変更する

      ターゲットディレクトリにカーソルを合わせ、edit アイコンをクリックして、ディレクトリの名前を変更します。ディレクトリ名はスラッシュ (/) で始めることはできません。

      ディレクトリを移動する

      ディレクトリを移動するには、ターゲットパスを指定する新しい名前を指定します。新しい名前がスラッシュ (/) で始まる場合、バケットのルートディレクトリからの絶対パスとして扱われます。必要に応じてターゲットディレクトリを入力します。

      • 親ディレクトリ destdir から親ディレクトリ destfolder にサブディレクトリ subdir を移動するには、新しい名前として /destfolder/subdir を入力します。

      • 親ディレクトリ destdir からバケットのルートディレクトリにサブディレクトリ subdir を移動するには、新しい名前として /subdir を入力します。

    SDK

    ディレクトリの名前変更は、バージョン 3.12.0 以降が必要な Java 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 com.aliyun.oss.model.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            // yourEndpoint をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
            String endPoint = "yourEndpoint";
            // アクセス資格情報をコードにハードコーディングしないでください。資格情報が漏洩すると、すべてのリソースのセキュリティが損なわれる可能性があります。この例では、環境変数から資格情報を取得します。コードを実行する前に環境変数を設定してください。
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // bucketName をバケットの名前に設定します (例: examplebucket)。
            String bucketName = "examplebucket";
            // sourceDir をソースディレクトリの絶対パスに設定します。絶対パスにバケット名を含めることはできません。
            String sourceDir = "exampledir";
            // destinationDir を宛先ディレクトリの絶対パスに設定します。これはソースディレクトリと同じバケットにある必要があります。絶対パスにバケット名を含めることはできません。
            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 リクエストを作成します。これを行うには、署名を計算するためのコードを手動で記述する必要があります。詳細については、「RenameObject」をご参照ください。

  • 階層的な名前空間機能が無効になっている場合は、ディレクトリ内のすべてのオブジェクトをリストし、新しいプレフィックスにコピーしてから、ソースオブジェクトを削除してディレクトリの名前を変更します。

    説明

    多数のオブジェクトをコピーするには、データオンライン移行を使用してバッチコピー操作を実行します。詳細については、「Alibaba Cloud OSS バケット間でデータを移行する」をご参照ください。

    ossutil

    ossutil を使用する場合は、コピーと削除のステップを手動で実行して、名前変更プロセスを完了します。

    1. オブジェクトのコピー
      cp コマンドと --recursive (-r) オプションを使用して、examplebucket バケット内の old-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. ターゲットバケットの [オブジェクト管理] > [オブジェクト] ページに移動します。

  3. 削除するディレクトリを選択し、[アクション] 列の [完全に削除] をクリックします。

  4. 表示されるダイアログボックスで、[OK] をクリックします。

    重要

    削除タスクの進行中にページをリフレッシュしたり閉じたりしないでください。操作が中断されます。

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 {
        // エンドポイントの例として、中国 (杭州) リージョンが使用されています。実際のリージョンに基づいてエンドポイントを指定してください。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // アクセス資格情報をコードにハードコーディングしないでください。資格情報が漏洩すると、すべてのリソースのセキュリティが損なわれる可能性があります。この例では、環境変数から資格情報を取得します。コードを実行する前に環境変数を設定してください。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // bucketName をバケットの名前に設定します (例: examplebucket)。
        String bucketName = "examplebucket";
        // directoryName をディレクトリの絶対パスに設定します。絶対パスにバケット名を含めることはできません。
        String directoryName = "exampledir";
        // prefix を削除するディレクトリの完全なパスに設定します。完全なパスにバケット名を含めることはできません。
        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 は、サーバーが次の削除の開始点を見つけるために使用されます。
            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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
$endpoint = "yourEndpoint";
// バケット名を設定します。
$bucket = "examplebucket";

try {
   $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
   $option = array(
      OssClient::OSS_MARKER => null,
      // OSS_PREFIX を削除するディレクトリの完全なパスに設定します。完全なパスにバケット名を含めることはできません。
      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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを 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: '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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
# バケット名を設定します。
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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // バケット名を設定します。
    bucket, err := client.Bucket("examplebucket")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    marker := oss.Marker("")
    // prefix を削除するディレクトリの完全なパスに設定します。完全なパスにバケット名を含めることはできません。
    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 をバケットが配置されているリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 */
    std::string Endpoint = "yourEndpoint";
    /* バケット名を設定します。 */
    std::string BucketName = "examplebucket";
    /* keyPrefix を削除するディレクトリの完全なパスに設定します。完全なパスにバケット名を含めることはできません。 */
    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 リクエストを直接作成します。これを行うには、署名を計算するためのコードを手動で記述する必要があります。詳細については、「DeleteObject」をご参照ください。

ディレクトリ内のオブジェクトの数とサイズのクエリ

方法 1: オブジェクトをリストして統計を取得する

10,000 未満など、比較的少数のオブジェクトを含むディレクトリに適しています。

  1. ターゲットバケットの左側のナビゲーションウィンドウで、オブジェクト管理 > オブジェクト を選択します。

  2. ターゲットディレクトリの右側にある統計アイコンをクリックします。

    filesize.jpg

方法 2: バケットインベントリを使用して定期的なクエリを実行する

数百万または数十億など、非常に多数のオブジェクトを含むディレクトリの定期的な分析に適しています。

  1. ターゲットバケットの左側のナビゲーションウィンドウで、データ管理 > バケットインベントリ を選択します。

  2. インベントリの作成 をクリックします。インベントリの作成 パネルで、インベントリ保存バケット を選択します。インベントリコンテンツについては、[オブジェクトサイズ] を選択します。[オブジェクトプレフィックス] には、クエリするディレクトリの名前 (例: random_files/) を入力します。他のパラメーターはデフォルト設定のままにします。

    screenshot_2025-07-04_18-14-09

  3. インベントリ結果を表示します。

    1. [オブジェクト] ページで、/Inventory Report Bucket/Inventory ID/data/ パスで生成されたインベントリファイルを見つけます。

    2. インベントリファイルをローカルマシンにダウンロードして、ディレクトリ内のファイルの数とサイズを表示します。

      インベントリファイルでは、列 A はバケット名を表し、列 B はディレクトリとその中のすべてのオブジェクトをリストし、列 C は対応する各オブジェクトのサイズを示します。

      screenshot_2025-07-04_18-28-44

詳細については、「バケットインベントリ」をご参照ください。

方法 3: MetaSearch を使用して複雑なクエリを実行する

特に、プレフィックス、時間、またはファイルタイプなどの柔軟なフィルタリング条件が必要な場合に、ディレクトリ内のオブジェクトの数とサイズに関するほぼリアルタイムの統計クエリに適しています。

  1. ターゲットバケットの左側のナビゲーションウィンドウで、オブジェクト管理 > データのインデックス作成 を選択します。

  2. [データインデックス] ページで、[データインデックスを有効にする] をクリックし、[MetaSearch] を選択して、[有効化] をクリックします。

    説明

    MetaSearch の有効化には、バケット内のオブジェクトの数によっては時間がかかる場合があります。

  3. [オブジェクト名][プレフィックス一致] に設定し、プレフィックスとして random_files/ を入力します。他のパラメーターはデフォルト設定のままにします。

    image

  4. 出力方法を設定します。

    • [オブジェクトの並べ替え順序][デフォルト] に設定します。

    • [データ集計] については、[オブジェクトサイズ][合計] を選択します。

      image

  5. [今すぐクエリ] をクリックします。結果には、random_files/ ディレクトリ内のすべてのオブジェクトの総数とサイズが表示されます。

    image

詳細については、「MetaSearch」をご参照ください。

本番環境での適用

アクセス制御

OSS は、ディレクトリプレースホルダーオブジェクト自体ではなく、オブジェクト名のプレフィックスマッチングに基づいてアクセス制御を行います。

たとえば、ユーザーに logs/ ディレクトリ内のすべてのオブジェクトへの読み取り専用アクセスを許可するには:

  • 誤り: 0 バイトの logs/ プレースホルダーオブジェクトに権限を設定します。

  • 正しい: Resource フィールドが acs:oss:*:*:your-bucket-name/logs/* に設定されている Resource Access Management (RAM) ポリシーを作成します。このポリシーは、logs/ プレフィックスで始まるすべてのオブジェクトに一致します。logs/ プレースホルダーオブジェクトが存在するかどうかは関係ありません。

パフォーマンスの最適化

  • ディレクトリの深さ: 深くネストされたディレクトリ構造 (例: a/b/c/d/.../file.log) は、リスト操作のパフォーマンスを低下させる可能性があるため、避けてください。

  • 大規模な名前変更: 多数のオブジェクトを含むディレクトリの名前を変更すると、大量の API 呼び出しとトラフィックが生成され、多額のコストが発生します。システム設計では、この慣行を避けてください。