重新命名及移動資料夾

本頁說明如何重新命名及移動已啟用階層式命名空間的值區中的資料夾。

重新命名作業會以遞迴方式重新命名資料夾、子資料夾和相關聯的資源,包括物件和受管理資料夾,且這項作業是不可分割的單一動作。

重新命名作業是不可部分完成的作業。作業會順利完成,並將資源移至新路徑,或因發生錯誤而失敗。如果發生錯誤,所有資源都會還原為原始狀態。

在啟用階層命名空間的 bucket 中,重新命名資料夾是僅限中繼資料的作業。這項作業不會實際移動或複製資料夾中的物件,因此不會產生物件副本費用。

不過,如果 bucket 未啟用階層結構式命名空間,系統會模擬資料夾。如要重新命名或移動模擬資料夾,必須複製並刪除其中的每個物件。如果資料夾包含許多物件,重新命名程序可能會效率不彰且成本高昂。重新命名或移動模擬資料夾也不是不可分割的操作,也就是說,如果程序失敗,儲存空間可能會處於不一致的狀態,只有部分物件會移動。

在資料夾重新命名過程中,您可以讀取及列出要重新命名的資源。 不過,您無法對受影響的資源執行寫入作業。

資料夾重新命名作業會啟動 bucket 的長期執行作業

事前準備

確認 bucket 已啟用階層命名空間。如需在 bucket 上啟用階層式命名空間的詳細操作說明,請參閱「建立已啟用階層式命名空間的 bucket」。

必要的角色

如要取得在值區中重新命名或移動資料夾所需的權限,請要求管理員授予您值區的「Storage 物件使用者」(roles/storage.objectUser) IAM 角色。

如要進一步瞭解如何授予專案角色,請參閱管理專案存取權

如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

  • storage.folders.rename
    • 來源資料夾必須具備這項權限。
  • storage.folders.create
    • 目的地資料夾必須具備這項權限。

您也可以透過其他自訂角色預先定義的角色取得上述權限。如要取得更寬鬆的權限,除了重新命名資料夾,還能管理資料夾,請管理員授予下列其中一個角色:

  • Storage 資料夾管理員 (roles/storage.folderAdmin)
  • Storage 物件管理員 (roles/storage.objectAdmin)
  • 儲存空間管理員 (roles/storage.admin)

如要查看哪些角色與哪些權限相關聯,請參閱「Cloud Storage 的 IAM 角色」。

重新命名及移動資料夾

控制台

  1. 在 Google Cloud 控制台,前往「Cloud Storage bucket」頁面。

    前往「Buckets」(值區) 頁面

  2. 在值區清單中,按一下包含要移動或重新命名資料夾的值區名稱。

  3. 在「Bucket details」(值區詳細資料) 頁面中,找出要移動或重新命名的資料夾。

  4. 如要重新命名資料夾,請按照下列步驟操作:

    1. 按一下資料夾的「更多動作」選單。

    2. 按一下「重新命名資料夾」

    3. 在出現的重疊視窗中,為資料夾輸入新名稱。

    4. 按一下 [重新命名]

  5. 如要將資料夾移至其他資料夾,請按照下列步驟操作:

    1. 按一下資料夾的「更多動作」選單。

    2. 按一下「移動資料夾」

    3. 在出現的重疊視窗中,按一下 [Browse] (瀏覽)。

    4. 選取要將資料夾移至哪個目標資料夾。您也可以先按一下 建立新資料夾,再選取該資料夾做為目的地資料夾。

    5. 按一下 [選取]。

    6. 按一下 [移動]

如要瞭解如何透過 Google Cloud 控制台取得 Cloud Storage 作業失敗的詳細錯誤資訊,請參閱「疑難排解」一文。

指令列

如要重新命名或移動 bucket 中具有階層式命名空間的資料夾,請執行 gcloud storage mv 指令:

gcloud storage mv gs://BUCKET_NAME/FOLDER1 gs://BUCKET_NAME/FOLDER2

其中:

  • BUCKET_NAME 是包含要重新命名或移動資料夾的值區名稱。例如:my-bucket
  • FOLDER1 是要重新命名或移動的原始資料夾名稱。例如:my-src-folder
  • FOLDER2 是目的地資料夾的新名稱。例如,my-dest-folder。如果新名稱與現有資料夾的名稱相同,系統會將原始資料夾移至現有資料夾中,成為子資料夾。舉例來說,如果將 my-dest-folder 重新命名為 my-dest-folder1 (且 my-dest-folder1 已存在),結果會是 my-dest-folder1/my-dest-folder/。如果選擇的新名稱不存在,系統會將原始資料夾重新命名為新名稱。

回應類似下列範例:

Copying gs://my-bucket/my-src-folder to gs://my-bucket/my-dest-folder...

用戶端程式庫

C++

詳情請參閱 Cloud Storage C++ API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

namespace storagecontrol = google::cloud::storagecontrol_v2;
[](storagecontrol::StorageControlClient client,
   std::string const& bucket_name, std::string const& source_folder_id,
   std::string const& dest_folder_id) {
  auto name = std::string{"projects/_/buckets/"} + bucket_name + "/folders/" +
              source_folder_id;
  // Start a rename operation and block until it completes. Real applications
  // may want to setup a callback, wait on a coroutine, or poll until it
  // completes.
  auto renamed = client.RenameFolder(name, dest_folder_id).get();
  if (!renamed) throw std::move(renamed).status();

  std::cout << "Renamed: " << source_folder_id << " to: " << dest_folder_id
            << "\n";
}

C#

詳情請參閱 Cloud Storage C# API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

using Google.Cloud.Storage.Control.V2;
using System;

public class StorageControlRenameFolderSample
{
    public Folder StorageControlRenameFolder(string bucketName = "your-unique-bucket-name",
        string sourceFolderName = "your_folder_name", string targetFolderName = "target_folder_name")
    {
        StorageControlClient storageControl = StorageControlClient.Create();

        string folderResourceName =
            // Set project to "_" to signify globally scoped bucket
            FolderName.FormatProjectBucketFolder("_", bucketName, sourceFolderName);

        var operation = storageControl.RenameFolder(folderResourceName, targetFolderName);
        var folder = operation.PollUntilCompleted().Result;

        Console.WriteLine($"Renamed folder {sourceFolderName} to {targetFolderName}");
        return folder;
    }
}

Go

詳情請參閱 Cloud Storage Go API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import (
	"context"
	"fmt"
	"io"
	"time"

	control "cloud.google.com/go/storage/control/apiv2"
	"cloud.google.com/go/storage/control/apiv2/controlpb"
)

// renameFolder changes the name of an existing folder.
func renameFolder(w io.Writer, bucket, src, dst string) error {
	// bucket := "bucket-name"
	// src := "original-folder-name"
	// dst := "new-folder-name"

	ctx := context.Background()
	client, err := control.NewStorageControlClient(ctx)
	if err != nil {
		return fmt.Errorf("NewStorageControlClient: %w", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*30)
	defer cancel()

	// Construct source folder path including the bucket name.
	srcPath := fmt.Sprintf("projects/_/buckets/%v/folders/%v", bucket, src)

	req := &controlpb.RenameFolderRequest{
		Name:                srcPath,
		DestinationFolderId: dst,
	}
	op, err := client.RenameFolder(ctx, req)
	if err != nil {
		return fmt.Errorf("RenameFolder(%q): %w", srcPath, err)
	}

	// Wait for long-running operation to complete.
	f, err := op.Wait(ctx)
	if err != nil {
		return fmt.Errorf("waiting for RenameFolder: %w", err)
	}

	fmt.Fprintf(w, "folder %v moved to new path %v", srcPath, f.Name)
	return nil
}

Java

詳情請參閱 Cloud Storage Java API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。


import com.google.api.gax.longrunning.OperationFuture;
import com.google.storage.control.v2.Folder;
import com.google.storage.control.v2.FolderName;
import com.google.storage.control.v2.RenameFolderMetadata;
import com.google.storage.control.v2.RenameFolderRequest;
import com.google.storage.control.v2.StorageControlClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public final class RenameFolder {

  public static void renameFolder(
      String bucketName, String sourceFolderName, String destinationFolderName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // The name of the bucket
    // String bucketName = "your-unique-bucket-name";

    // The name of the folder within the bucket
    // String sourceFolderName = "your-unique-source-folder-name";

    // The new name of the folder within the bucket
    // String destinationFolderName = "your-unique-destination-folder-name";

    try (StorageControlClient storageControl = StorageControlClient.create()) {

      // Set project to "_" to signify globally scoped bucket
      String sourceFolderResourceName = FolderName.format("_", bucketName, sourceFolderName);
      RenameFolderRequest request =
          RenameFolderRequest.newBuilder()
              .setName(sourceFolderResourceName)
              .setDestinationFolderId(destinationFolderName)
              .build();

      OperationFuture<Folder, RenameFolderMetadata> renameOperation =
          storageControl.renameFolderAsync(request);

      Folder destinationFolder = renameOperation.get(30, TimeUnit.SECONDS);

      System.out.printf(
          "Renamed folder from %s to %s%n", sourceFolderResourceName, destinationFolder.getName());
    }
  }
}

Node.js

詳情請參閱 Cloud Storage Node.js API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */

// The name of your GCS bucket
// const bucketName = 'bucketName';

// The source folder name
// const sourceFolderName = 'currentFolderName';

// The destination folder ID
// const destinationFolderName = 'destinationFolderName';

// Imports the Control library
const {StorageControlClient} = require('@google-cloud/storage-control').v2;

// Instantiates a client
const controlClient = new StorageControlClient();

async function callRenameFolder() {
  const folderPath = controlClient.folderPath(
    '_',
    bucketName,
    sourceFolderName
  );

  // Create the request
  const request = {
    name: folderPath,
    destinationFolderId: destinationFolderName,
  };

  // Run request
  await controlClient.renameFolder(request);
  console.log(
    `Renamed folder ${sourceFolderName} to ${destinationFolderName}.`
  );
}

callRenameFolder();

PHP

詳情請參閱 Cloud Storage PHP API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

use Google\Cloud\Storage\Control\V2\Client\StorageControlClient;
use Google\Cloud\Storage\Control\V2\RenameFolderRequest;

/**
 * Rename a folder in an existing bucket.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $sourceFolder The source folder ID.
 *        (e.g. 'my-folder')
 * @param string $destinationFolder The destination folder ID.
 *        (e.g. 'my-folder')
 */
function rename_folder(string $bucketName, string $sourceFolder, string $destinationFolder): void
{
    $storageControlClient = new StorageControlClient();

    // Set project to "_" to signify global bucket
    $formattedName = $storageControlClient->folderName('_', $bucketName, $sourceFolder);

    $request = new RenameFolderRequest([
        'name' => $formattedName,
        'destination_folder_id' => $destinationFolder,
    ]);

    $storageControlClient->renameFolder($request);

    printf('Renamed folder %s to %s', $sourceFolder, $destinationFolder);
}

Python

詳情請參閱 Cloud Storage Python API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

from google.cloud import storage_control_v2


def rename_folder(
    bucket_name: str, source_folder_name: str, destination_folder_name: str
) -> None:
    # The ID of your GCS bucket
    # bucket_name = "your-unique-bucket-name"
    #
    # The source folder ID
    # source_folder_name = "current-folder-name"
    #
    # The destination folder ID
    # destination_folder_name = "new-folder-name"

    storage_control_client = storage_control_v2.StorageControlClient()
    # The storage bucket path uses the global access pattern, in which the "_"
    # denotes this bucket exists in the global namespace.
    source_folder_path = storage_control_client.folder_path(
        project="_", bucket=bucket_name, folder=source_folder_name
    )

    request = storage_control_v2.RenameFolderRequest(
        name=source_folder_path,
        destination_folder_id=destination_folder_name,
    )

    operation = storage_control_client.rename_folder(request=request)
    operation.result(60)

    print(f"Renamed folder {source_folder_name} to {destination_folder_name}")

Ruby

詳情請參閱 Cloud Storage Ruby API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

def rename_folder bucket_name:, source_folder_id:, destination_folder_id:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"
  #
  # The source folder ID
  # source_folder_id = "current-folder-id"
  #
  # The destination folder ID, e.g. foo/bar/
  # destination_folder_id = "destination-folder-id"

  require "google/cloud/storage/control"

  storage_control = Google::Cloud::Storage::Control.storage_control

  # The storage folder path uses the global access pattern, in which the "_"
  # denotes this bucket exists in the global namespace.
  folder_path = storage_control.folder_path project: "_", bucket: bucket_name, folder: source_folder_id

  request = Google::Cloud::Storage::Control::V2::RenameFolderRequest.new name: folder_path,
                                                                         destination_folder_id: destination_folder_id

  storage_control.rename_folder request

  puts "Renamed folder #{source_folder_id} to #{destination_folder_id}"
end

REST API

JSON API

  1. 安裝並初始化 gcloud CLI,以便為 Authorization 標頭產生存取權杖。

  2. 使用 cURL 透過重新命名資料夾的要求呼叫 JSON API

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/folders/SOURCE_PATH/renameTo/folders/DESTINATION_PATH"

    其中:

    • BUCKET_NAME 是包含要重新命名或移動資料夾的值區名稱。例如:my-bucket
    • SOURCE_PATH 是來源資料夾的 URL 編碼路徑。舉例來說,my-src-folder/ 經過網址編碼後會變成 my-src-folder%2F
    • DESTINATION_PATH 是經過網址編碼的目標資料夾路徑。舉例來說,my-dest-folder/ 經過網址編碼後會變成 my-dest-folder%2F

後續步驟

歡迎試用

如果您未曾使用過 Google Cloud,歡迎建立帳戶,親自體驗實際使用 Cloud Storage 的成效。新客戶可以獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。

免費試用 Cloud Storage