다음을 통해 공유


.NET을 사용하여 비동기 일정으로 Blob 복사

이 문서에서는 .NET용 Azure Storage 클라이언트 라이브러리를 사용하여 비동기 일정으로 Blob을 복사하는 방법을 보여 줍니다. 동일한 스토리지 계정 내의 원본, 다른 스토리지 계정의 원본 또는 지정된 URL의 HTTP GET 요청을 통해 검색되어 액세스 가능한 개체에서 Blob을 복사할 수 있습니다. 보류 중인 복사 작업을 중단할 수도 있습니다.

이 문서에서 다루는 클라이언트 라이브러리 메서드는 Blob 복사 REST API 작업을 사용하며 비동기 일정으로 복사를 수행하려는 경우에 사용할 수 있습니다. 데이터를 스토리지 계정으로 이동하고 원본 개체에 대한 URL을 포함하려는 대부분의 복사 시나리오에 대해서는 .NET을 사용하여 원본 개체 URL에서 Blob 복사를 참조하세요.

필수 조건

환경 설정

기존 프로젝트가 없는 경우, 이 섹션에서는 .NET용 Azure Blob Storage 클라이언트 라이브러리를 사용해서 작동하도록 프로젝트를 설정하는 방법을 보여 줍니다. 이 단계에는 패키지 설치, using 지시문 추가 및 권한이 있는 클라이언트 개체 만들기가 포함됩니다. 자세한 내용은 Azure Blob Storage 및 .NET 시작을 참조하세요.

패키지 설치

프로젝트 디렉터리에서 dotnet add package 명령을 사용하여 Azure Blob Storage 및 Azure ID 클라이언트 라이브러리용 패키지를 설치합니다. Azure 서비스에 암호 없이 연결하려면 Azure.Identity 패키지가 필요합니다.

dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Identity

using 지시문 추가

코드 파일 맨 위에 다음과 같이 using 지시문을 추가합니다.

using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

이 게시물의 일부 코드 예제에는 using 지시문이 추가로 필요할 수 있습니다.

클라이언트 개체 만들기

Blob Storage에 앱을 연결하려면 BlobServiceClient의 인스턴스를 만듭니다. 다음 예에서는 권한 부여를 위해 DefaultAzureCredential을 사용하여 클라이언트 개체를 만드는 방법을 설명합니다.

public BlobServiceClient GetBlobServiceClient(string accountName)
{
    BlobServiceClient client = new(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());

    return client;
}

.NET 앱에서 종속성 주입을 위한 서비스 클라이언트를 등록할 수 있습니다.

특정 컨테이너 또는 Blob을 위한 클라이언트 개체도 만들 수 있습니다. 클라이언트 개체 만들기 및 관리에 대한 자세한 내용은 데이터 리소스와 상호 작용하는 클라이언트 개체 만들기 및 관리를 참조하세요.

권한 부여

권한 부여 메커니즘에는 복사 작업을 수행하거나 보류 중인 복사를 중단하는 데 필요한 권한이 있어야 합니다. Microsoft Entra ID를 통한 권한 부여(권장)의 경우, 권한이 가장 낮은 Azure RBAC 기본 제공 역할은 여러 가지 요소에 따라 달라집니다. 자세한 내용은 Blob 복사(REST API) 또는 Blob 복사 중단(REST API)에 대한 권한 부여 지침을 참조하세요.

비동기 일정으로 Blob 복사 정보

Copy Blob 작업은 비동기적으로 완료될 수 있으며 최선의 노력으로 수행됩니다. 즉, 작업이 즉시 시작되거나 지정된 시간 프레임 내 완료된다고 보장되지 않습니다. 복사 작업은 백그라운드에서 예약되고 서버에 사용 가능한 리소스가 있을 때 수행됩니다. 복사가 동일한 스토리지 계정 내에서 발생하는 경우 작업은 동기적으로 완료할 수 있습니다.

Copy Blob 작업은 다음 작업을 수행할 수 있습니다.

  • 다른 이름을 사용해서 원본 Blob을 대상 Blob에 복사합니다. 대상 Blob은 동일한 Blob 유형(블록, 추가 또는 페이지)의 기존 Blob이거나 복사 작업으로 생성된 새 Blob일 수 있습니다.
  • 동일한 이름을 사용해 원본 Blob을 대상 Blob으로 복사하여 대상 Blob을 바꿀 수 있습니다. 이 유형의 복사 작업은 커밋되지 않은 블록을 제거하고 대상 Blob의 메타데이터를 덮어씁니다.
  • Azure 파일 서비스의 원본 파일을 대상 Blob에 복사합니다. 대상 blob은 기존 블록 Blob이거나 복사 작업을 통해 만든 새 블록 Blob일 수 있습니다. 파일에서 페이지 Blob 또는 추가 Blob으로 복사하는 것은 지원되지 않습니다.
  • 기본 Blob에 대해 스냅샷을 복사합니다. 스냅샷의 수준을 기본 Blob 위치로 올리면 이전 Blob 버전을 복원할 수 있습니다.
  • 스냅샷을 다른 이름으로 대상 Blob에 복사합니다. 복사된 대상 Blob는 쓰기 가능한 Blob이고 스냅샷이 아닙니다.

속성, 인덱스 태그, 메타데이터 및 청구에 대한 정보를 포함하여 Copy Blob 작업에 대한 자세한 내용은 Blob 설명 복사를 참조하세요.

비동기 일정으로 BLOB 복사

이 섹션에서는 비동기 일정으로 복사 작업을 수행하기 위해 .NET용 Azure Storage 클라이언트 라이브러리에서 제공하는 메서드에 대한 개요를 제공합니다.

다음 메서드는 BLOB 복사 REST API 작업을 래핑하고 원본 BLOB에서 데이터의 비동기 복사를 시작합니다.

StartCopyFromUriStartCopyFromUriAsync 메서드는 복사 작업에 대한 정보가 포함된 CopyFromUriOperation 개체를 반환합니다. 이러한 메서드는 복사 작업에 대한 비동기 일정을 원할 때 사용됩니다.

Azure 내 원본에서 Blob 복사

동일한 스토리지 계정 내에서 Blob을 복사하는 경우 작업을 동기적으로 완료할 수 있습니다. 원본 Blob에 대한 액세스는 Microsoft Entra ID, SAS(공유 액세스 서명) 또는 계정 키를 통해 권한 부여될 수 있습니다. 다른 동기 복사 작업에 대해서는 .NET으로 원본 개체 URL에서 BLOB 복사를 참조하세요.

복사 원본이 다른 스토리지 계정의 BLOB인 경우 작업을 비동기적으로 완료할 수 있습니다. 원본 Blob은 공용이거나 SAS 토큰을 통해 권한이 부여되어야 합니다. SAS 토큰에는 읽기(‘r’) 권한이 포함되어야 합니다. SAS 토큰에 대한 자세한 내용은 공유 액세스 서명을 사용하여 액세스 위임을 참조하세요.

다음 예제에서는 비동기 일정으로 다른 스토리지 계정에서 원본 Blob을 복사하는 시나리오를 보여 줍니다. 이 예제에서는 추가된 사용자 위임 SAS 토큰을 사용하여 원본 Blob URL을 만듭니다. 이 예제에서는 클라이언트 라이브러리를 사용하여 SAS 토큰을 생성하는 방법을 보여 주지만, 직접 제공할 수도 있습니다. 또한 이 예제에서는 복사 작업 중에 원본 Blob을 임대하여 다른 클라이언트에서 Blob에 대한 변경 내용을 방지하는 방법을 보여줍니다. Copy Blob 작업은 복사 작업이 시작될 때 원본 Blob의 ETag 값을 저장합니다. 복사 작업이 완료되기 전에 ETag 값이 변경되면 작업이 실패합니다.

//-------------------------------------------------
// Copy a blob from a different storage account
//-------------------------------------------------
public static async Task CopyAcrossStorageAccountsAsync(
    BlobClient sourceBlob,
    BlockBlobClient destinationBlob)
{
    // Lease the source blob to prevent changes during the copy operation
    BlobLeaseClient sourceBlobLease = new(sourceBlob);

    // Create a Uri object with a SAS token appended - specify Read (r) permissions
    Uri sourceBlobSASURI = await GenerateUserDelegationSAS(sourceBlob);

    try
    {
        await sourceBlobLease.AcquireAsync(BlobLeaseClient.InfiniteLeaseDuration);

        // Start the copy operation and wait for it to complete
        CopyFromUriOperation copyOperation = await destinationBlob.StartCopyFromUriAsync(sourceBlobSASURI);
        await copyOperation.WaitForCompletionAsync();
    }
    catch (RequestFailedException ex)
    {
        // Handle the exception
    }
    finally
    {
        // Release the lease once the copy operation completes
        await sourceBlobLease.ReleaseAsync();
    }
}

async static Task<Uri> GenerateUserDelegationSAS(BlobClient sourceBlob)
{
    BlobServiceClient blobServiceClient =
        sourceBlob.GetParentBlobContainerClient().GetParentBlobServiceClient();

    // Get a user delegation key for the Blob service that's valid for 1 day
    UserDelegationKey userDelegationKey =
        await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                          DateTimeOffset.UtcNow.AddDays(1));

    // Create a SAS token that's also valid for 1 day
    BlobSasBuilder sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = sourceBlob.BlobContainerName,
        BlobName = sourceBlob.Name,
        Resource = "b",
        StartsOn = DateTimeOffset.UtcNow,
        ExpiresOn = DateTimeOffset.UtcNow.AddDays(1)
    };

    // Specify read permissions for the SAS
    sasBuilder.SetPermissions(BlobSasPermissions.Read);

    // Add the SAS token to the blob URI
    BlobUriBuilder blobUriBuilder = new BlobUriBuilder(sourceBlob.Uri)
    {
        // Specify the user delegation key
        Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                              blobServiceClient.AccountName)
    };

    return blobUriBuilder.ToUri();
}

참고 항목

사용자 위임 SAS 토큰은 계정 키 대신 Microsoft Entra 자격 증명으로 서명되므로 더 강력한 보안을 제공합니다. 사용자 위임 SAS 토큰을 만들려면 Microsoft Entra 보안 주체에 적절한 권한이 필요합니다. 권한 부여 요구 사항은 사용자 위임 키 가져오기를 참조하세요.

Azure 외부의 원본에서 Blob 복사

Azure 외부의 액세스 가능한 개체를 포함하여 지정된 URL에서 HTTP GET 요청을 통해 검색할 수 있는 모든 원본 개체에 대해 복사 작업을 수행할 수 있습니다. 다음 예제에서는 액세스 가능한 원본 개체 URL에서 Blob을 복사하는 시나리오를 보여줍니다.

//-------------------------------------------------
// Copy a blob from an external source
//-------------------------------------------------
public static async Task CopyFromExternalSourceAsync(
    string sourceLocation,
    BlockBlobClient destinationBlob)
{
    Uri sourceUri = new(sourceLocation);

    // Start the copy operation and wait for it to complete
    CopyFromUriOperation copyOperation = await destinationBlob.StartCopyFromUriAsync(sourceUri);
    await copyOperation.WaitForCompletionAsync();
}

복사 작업의 상태 확인

Copy Blob 작업의 상태를 확인하려면 UpdateStatusAsync를 호출하고 응답을 구문 분석하여 x-ms-copy-status 헤더에 대한 값을 가져올 수 있습니다.

다음 코드 예제에서는 복사 작업의 상태를 확인하는 방법을 보여 줍니다.

public static async Task CheckCopyStatusAsync(CopyFromUriOperation copyOperation)
{
    // Check for the latest status of the copy operation
    Response response = await copyOperation.UpdateStatusAsync();

    // Parse the response to find x-ms-copy-status header
    if (response.Headers.TryGetValue("x-ms-copy-status", out string value))
        Console.WriteLine($"Copy status: {value}");
}

복사 작업 중단

보류 중인 Copy Blob 작업을 중단하면 대상 Blob의 길이가 0이 됩니다. 하지만 대상 Blob의 메타데이터는 원본 Blob에서 복사되었거나 복사 작업 중에 명시적으로 설정된 새 값을 가집니다. 복사 전의 원본 메타데이터를 보존하려면 복사 메서드 중 하나를 호출하기 전에 대상 Blob의 스냅샷을 만듭니다.

보류 중인 복사 작업을 중단하려면 다음 작업 중 하나를 호출합니다.

이러한 메서드는 Blob 복사 중단 REST API 작업을 래핑하여, 보류 중인 Copy Blob 작업을 취소합니다. 다음 코드 예제에서는 보류 중인 Copy Blob 작업을 중단하는 방법을 보여줍니다.

public static async Task AbortBlobCopyAsync(
    CopyFromUriOperation copyOperation,
    BlobClient destinationBlob)
{
    // Check for the latest status of the copy operation
    Response response = await copyOperation.UpdateStatusAsync();

    // Parse the response to find x-ms-copy-status header
    if (response.Headers.TryGetValue("x-ms-copy-status", out string value))
    {
        if (value == "pending")
        {
            await destinationBlob.AbortCopyFromUriAsync(copyOperation.Id);
            Console.WriteLine($"Copy operation {copyOperation.Id} aborted");
        }
    }
}

리소스

.NET용 Azure Blob Storage 클라이언트 라이브러리를 사용하여 Blob을 복사하는 방법에 대해 자세히 알아보려면 다음 리소스를 참조하세요.

코드 샘플

REST API 작업

.NET용 Azure SDK에는 Azure REST API를 기반으로 빌드되는 라이브러리가 포함되어 있으므로 익숙한 .NET 패러다임을 통해 REST API 작업과 상호 작용할 수 있습니다. 이 문서에서 다루는 클라이언트 라이브러리 메서드는 다음 REST API 작업을 사용합니다.

클라이언트 라이브러리 리소스

  • 이 문서는 .NET용 Blob Storage 개발자 가이드의 일부입니다. 자세한 내용은 .NET 앱 빌드에서 개발자 가이드 문서의 전체 목록을 참조하세요.