programing

Azure Storage Client 2.0의 다른 BLOB로 한 Azure Blob 복사

goodsources 2023. 5. 26. 20:55
반응형

Azure Storage Client 2.0의 다른 BLOB로 한 Azure Blob 복사

이전의 1.7 스토리지 클라이언트에는 CloudBlub가 있었습니다.CopyFromBlob(다른 Blob) 메서드는 2.0 버전에는 없는 것 같습니다.블롭을 복사하기 위한 권장 모범 사례는 무엇입니까?저는 구름 방울을 봅니다.StartCopyFromBlob 메서드를 시작합니다.그것이 적절한 방법이라면, 어떻게 사용해야 합니까?

Gaurav Mantri는 Azure Storage 버전 2.0에 대한 일련의 기사를 작성했습니다. 코드는 그의 블로그 게시물인 Storage Client Library 2.0 – Blob Copy용 Blob 스토리지 코드 마이그레이션에서 발췌한 것입니다.

CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = cloudBlobClient.GetContainerReference(containerName);
CloudBlobContainer targetContainer = cloudBlobClient.GetContainerReference(targetContainerName);
string blobName = "<Blob Name e.g. myblob.txt>";
CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference(blobName);
CloudBlockBlob targetBlob = targetContainer.GetBlockBlobReference(blobName);
targetBlob.StartCopyFromBlob(sourceBlob);

Storage 6.3(원래 질문보다 훨씬 새로운 라이브러리) 및 비동기 방법 사용 StartCopyAsync(MSDN)

  CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Your Connection");

  CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  CloudBlobContainer container = blobClient.GetContainerReference("YourContainer");

  CloudBlockBlob source = container.GetBlockBlobReference("Your Blob");
  CloudBlockBlob target = container.GetBlockBlobReference("Your New Blob");
        
  await target.StartCopyAsync(source);

최신 버전 (7.x) 기준 FYISDK이것은 더 이상 작동하지 않습니다 왜냐하면BeginStartCopyBlob함수가 더 이상 존재하지 않습니다.

다음과 같은 방법으로 수행할 수 있습니다.

// this tunnels the data via your program,
// so it reuploads the blob instead of copying it on service side
using (var stream = await sourceBlob.OpenReadAsync())
{
  await destinationBlob.UploadFromStreamAsync(stream);
}

@(Alexey Shcherbak)가 언급한 것처럼 이것이 진행하는 더 나은 방법입니다.

await targetCloudBlob.StartCopyAsync(sourceCloudBlob.Uri);

while (targetCloudBlob.CopyState.Status == CopyStatus.Pending)
{
    await Task.Delay(500);
    // Need to fetch or "CopyState" will never update
    await targetCloudBlob.FetchAttributesAsync(); 
}

if (targetCloudBlob.CopyState.Status != CopyStatus.Success)
{
    throw new Exception("Copy failed: " + targetCloudBlob.CopyState.Status);
}

Azure Storage 8을 시작합니다. 스토리지 계정 간에 Blobs를 이동하려면 아래와 유사한 코드를 사용합니다. 누군가에게 도움이 되기를 바랍니다.

//copy blobs - from
CloudStorageAccount sourceStorageAccount = new CloudStorageAccount(new StorageCredentials(storageFromName, storageFromKey), true);
CloudBlobClient sourceCloudBlobClient = sourceStorageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = sourceCloudBlobClient.GetContainerReference(containerFromName);

//copy blobs - to
CloudStorageAccount targetStorageAccount = new CloudStorageAccount(new StorageCredentials(storageToName, storageToKey), true);
CloudBlobClient targetCloudBlobClient = targetStorageAccount.CreateCloudBlobClient();
CloudBlobContainer targetContainer = targetCloudBlobClient.GetContainerReference(containerToName);

//create target container if didn't exists
try{
    await targetContainer.CreateIfNotExistsAsync();
}
catch(Exception e){
    log.Error(e.Message);
}

CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference(blobName);
CloudBlockBlob targetBlob = targetContainer.GetBlockBlobReference(blobName);

try{
    //initialize copying
    await targetBlob.StartCopyAsync(sourceBlob.Uri);
}
catch(Exception ex){
    log.Error(ex.Message);
    //return error, in my case HTTP
    return req.CreateResponse(HttpStatusCode.BadRequest, "Error, source BLOB probably has private access only: " +ex.Message);
} 

//fetch current attributes
targetBlob.FetchAttributes();

//waiting for completion
while (targetBlob.CopyState.Status == CopyStatus.Pending){
    log.Info("Status: " + targetBlob.CopyState.Status);
    Thread.Sleep(500);
    targetBlob.FetchAttributes();
}

//check status
if (targetBlob.CopyState.Status != CopyStatus.Success){
    //return error, in my case HTTP
    return req.CreateResponse(HttpStatusCode.BadRequest, "Copy failed with status: " + targetBlob.CopyState.Status);
}

//finally remove source in case Copy Status was Success
sourceBlob.Delete();

//and return success (in my case HTTP)
return req.CreateResponse(HttpStatusCode.OK, "Done.");

Naven은 이미 올바른 구문을 설명했습니다.StartCopyFromBlob(동기식 방법).말씀하신 방법 (BeginStartCopyFromBlob)는 사용자가 사용할 수 있는 비동기식 대안입니다.Task예:

    var blobClient = account.CreateCloudBlobClient();

    // Upload picture.
    var picturesContainer = blobClient.GetContainerReference("pictures");
    picturesContainer.CreateIfNotExists();
    var myPictureBlob = picturesContainer.GetBlockBlobReference("me.png");
    using (var fs = new FileStream(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg", FileMode.Open))
        myPictureBlob.UploadFromStream(fs);

    // Backup picture.
    var backupContainer = blobClient.GetContainerReference("backup");
    backupContainer.CreateIfNotExists();
    var backupBlob = picturesContainer.GetBlockBlobReference("me.png");

    var task = Task.Factory.FromAsync<string>(backupBlob.BeginStartCopyFromBlob(myPictureBlob, null, null), backupBlob.EndStartCopyFromBlob);
    task.ContinueWith((t) =>
    {
        if (!t.IsFaulted)
        {
            while (true)
            {
                Console.WriteLine("Copy state for {0}: {1}", backupBlob.Uri, backupBlob.CopyState.Status);
                Thread.Sleep(500);
            }
        }
        else
        {
            Console.WriteLine("Error: " + t.Exception);
        }
    });

저는 Windows Azure.스토리지 8.0.1, James Hancock의 솔루션은 서버 측 복사를 수행했지만 클라이언트 복사 상태는 계속 유지되었습니다.Pending(Looping forever).해결책은 전화하는 것이었습니다.FetchAttributes()targetCloudBlob끝나고Thread.sleep(500).

// Aaron Sherman's code 

targetCloudBlob.StartCopy(sourceCloudBlob.Uri);

while (targetCloudBlob.CopyState.Status == CopyStatus.Pending)
{
    Thread.Sleep(500);
    targetCloudBlob.FetchAttributes();
}

// James Hancock's remaining code

마이크로소프트 공식 설명서(비동기화 예제)

이전 게시물들이 만들어졌기 때문에 API가 조금 정리되었을 것으로 보입니다.

// _client is a BlobServiceClient injected via DI in the constructor.

BlobContainerClient sourceContainerClient = _client.GetBlobContainerClient(sourceContainerName);
BlobClient sourceClient = sourceContainerClient.GetBlobClient(blobName);

BlobContainerClient destContainerClient = _client.GetBlobContainerClient(destContainerName);
BlobClient destClient = destContainerClient.GetBlobClient(blobName);

// assume that if the following doesn't throw an exception, then it is successful.
CopyFromUriOperation operation = await destClient.StartCopyFromUriAsync(sourceClient.Uri);
await operation.WaitForCompletionAsync();

다음에 대한 설명서operation.WaitForCompletionAsync다음과 같이 말합니다.

장기 실행 작업이 완료될 때까지 주기적으로 서버를 호출합니다.이 메서드는 주기적으로 UpdateStatusAsync to HasCompleted가 true일 때까지 호출한 다음 작업의 최종 결과를 반환합니다.

이 메서드에 대한 소스 코드를 검토하는 중에 호출된 것 같습니다.BlobBaseClient.GetProperties(또는 비동기 버전)을 던질 것입니다.RequestFailureException잘못하여

여기 저의 짧고 간단한 대답이 있습니다.

public void Copy(CloudBlockBlob srcBlob, CloudBlobContainer destContainer)
{
    CloudBlockBlob destBlob;

    if (srcBlob == null)
    {
        throw new Exception("Source blob cannot be null.");
    }

    if (!destContainer.Exists())
    {
        throw new Exception("Destination container does not exist.");
    }

    //Copy source blob to destination container
    string name = srcBlob.Uri.Segments.Last();
    destBlob = destContainer.GetBlockBlobReference(name);
    destBlob.StartCopyAsync(srcBlob);                
}

언급URL : https://stackoverflow.com/questions/14152087/copying-one-azure-blob-to-another-blob-in-azure-storage-client-2-0

반응형