Bagikan melalui


Sampel kode Azure Blob Storage menggunakan pustaka klien .NET versi 11.x

Artikel ini memperlihatkan sampel kode yang menggunakan versi 11.x dari pustaka klien Azure Blob Storage untuk .NET.

Pada 31 Maret 2023, kami menghentikan dukungan untuk pustaka Azure SDK yang tidak sesuai dengan pedoman Azure SDK saat ini. Pustaka Azure SDK baru diperbarui secara teratur untuk mendorong pengalaman yang konsisten dan memperkuat postur keamanan Anda. Disarankan agar Anda beralih ke pustaka Azure SDK baru untuk memanfaatkan kemampuan baru dan pembaruan keamanan penting.

Meskipun pustaka yang lebih lama masih dapat digunakan melebihi 31 Maret 2023, pustaka tersebut tidak akan lagi menerima dukungan dan pembaruan resmi dari Microsoft. Untuk informasi selengkapnya, lihat pengumuman penghentian layanan dukungan.

Membuat rekam jepret

Untuk membuat rekam jepret blob blok menggunakan versi 11.x dari pustaka klien Azure Storage untuk .NET, gunakan salah satu metode berikut:

Contoh kode berikut menunjukkan cara membuat rekam jepret dengan versi 11.x. Contoh ini menentukan metadata tambahan untuk rekam jepret saat dibuat.

private static async Task CreateBlockBlobSnapshot(CloudBlobContainer container)
{
    // Create a new block blob in the container.
    CloudBlockBlob baseBlob = container.GetBlockBlobReference("sample-base-blob.txt");

    // Add blob metadata.
    baseBlob.Metadata.Add("ApproxBlobCreatedDate", DateTime.UtcNow.ToString());

    try
    {
        // Upload the blob to create it, with its metadata.
        await baseBlob.UploadTextAsync(string.Format("Base blob: {0}", baseBlob.Uri.ToString()));

        // Sleep 5 seconds.
        System.Threading.Thread.Sleep(5000);

        // Create a snapshot of the base blob.
        // You can specify metadata at the time that the snapshot is created.
        // If no metadata is specified, then the blob's metadata is copied to the snapshot.
        Dictionary<string, string> metadata = new Dictionary<string, string>();
        metadata.Add("ApproxSnapshotCreatedDate", DateTime.UtcNow.ToString());
        await baseBlob.CreateSnapshotAsync(metadata, null, null, null);
        Console.WriteLine(snapshot.SnapshotQualifiedStorageUri.PrimaryUri);
    }
    catch (StorageException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

Menghapus snapshot

Untuk menghapus blob dan rekam jepretnya menggunakan versi 11.x dari pustaka klien Azure Storage untuk .NET, gunakan salah satu metode penghapusan blob berikut, dan sertakan enum DeleteSnapshotsOption:

Contoh kode berikut menunjukkan cara menghapus blob dan rekam jepretnya di .NET, di mana blockBlob adalah objek jenis [CloudBlockBlob][dotnet_CloudBlockBlob]:

await blockBlob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots, null, null, null);

Membuat kebijakan akses tersimpan

Untuk membuat kebijakan akses tersimpan pada kontainer dengan versi 11.x dari pustaka klien .NET untuk Azure Storage, panggil salah satu metode berikut:

Contoh berikut membuat kebijakan akses tersimpan yang berlaku selama satu hari dan yang memberikan izin baca, tulis, dan daftar:

private static async Task CreateStoredAccessPolicyAsync(CloudBlobContainer container, string policyName)
{
    // Create a new stored access policy and define its constraints.
    // The access policy provides create, write, read, list, and delete permissions.
    SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
    {
        // When the start time for the SAS is omitted, the start time is assumed to be the time when Azure Storage receives the request.
        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
        Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List |
            SharedAccessBlobPermissions.Write
    };

    // Get the container's existing permissions.
    BlobContainerPermissions permissions = await container.GetPermissionsAsync();

    // Add the new policy to the container's permissions, and set the container's permissions.
    permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
    await container.SetPermissionsAsync(permissions);
}

Buat layanan SAS untuk kontainer blob

Untuk membuat SAS layanan untuk kontainer, panggil metode CloudBlobContainer.GetSharedAccessSignature.

private static string GetContainerSasUri(CloudBlobContainer container,
                                         string storedPolicyName = null)
{
    string sasContainerToken;

    // If no stored policy is specified, create a new access policy and define its constraints.
    if (storedPolicyName == null)
    {
        // Note that the SharedAccessBlobPolicy class is used both to define
        // the parameters of an ad hoc SAS, and to construct a shared access policy
        // that is saved to the container's shared access policies.
        SharedAccessBlobPolicy adHocPolicy = new SharedAccessBlobPolicy()
        {
            // When the start time for the SAS is omitted, the start time is assumed
            // to be the time when the storage service receives the request. Omitting
            // the start time for a SAS that is effective immediately helps to avoid clock skew.
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
            Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
        };

        // Generate the shared access signature on the container,
        // setting the constraints directly on the signature.
        sasContainerToken = container.GetSharedAccessSignature(adHocPolicy, null);

        Console.WriteLine("SAS for blob container (ad hoc): {0}", sasContainerToken);
        Console.WriteLine();
    }
    else
    {
        // Generate the shared access signature on the container. In this case,
        // all of the constraints for the shared access signature are specified
        // on the stored access policy, which is provided by name. It is also possible
        // to specify some constraints on an ad hoc SAS and others on the stored access policy.
        sasContainerToken = container.GetSharedAccessSignature(null, storedPolicyName);

        Console.WriteLine("SAS for container (stored access policy): {0}", sasContainerToken);
        Console.WriteLine();
    }

    // Return the URI string for the container, including the SAS token.
    return container.Uri + sasContainerToken;
}

Buat layanan SAS untuk blob

Untuk membuat SAS untuk layanan blob, panggil metode CloudBlob.GetSharedAccessSignature.

private static string GetBlobSasUri(CloudBlobContainer container,
                                    string blobName,
                                    string policyName = null)
{
    string sasBlobToken;

    // Get a reference to a blob within the container.
    // Note that the blob may not exist yet, but a SAS can still be created for it.
    CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

    if (policyName == null)
    {
        // Create a new access policy and define its constraints.
        // Note that the SharedAccessBlobPolicy class is used both to define the parameters
        // of an ad hoc SAS, and to construct a shared access policy that is saved to
        // the container's shared access policies.
        SharedAccessBlobPolicy adHocSAS = new SharedAccessBlobPolicy()
        {
            // When the start time for the SAS is omitted, the start time is assumed to be
            // the time when the storage service receives the request. Omitting the start time
            // for a SAS that is effective immediately helps to avoid clock skew.
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
            Permissions = SharedAccessBlobPermissions.Read |
                          SharedAccessBlobPermissions.Write |
                          SharedAccessBlobPermissions.Create
        };

        // Generate the shared access signature on the blob,
        // setting the constraints directly on the signature.
        sasBlobToken = blob.GetSharedAccessSignature(adHocSAS);

        Console.WriteLine("SAS for blob (ad hoc): {0}", sasBlobToken);
        Console.WriteLine();
    }
    else
    {
        // Generate the shared access signature on the blob. In this case, all of the constraints
        // for the SAS are specified on the container's stored access policy.
        sasBlobToken = blob.GetSharedAccessSignature(null, policyName);

        Console.WriteLine("SAS for blob (stored access policy): {0}", sasBlobToken);
        Console.WriteLine();
    }

    // Return the URI string for the container, including the SAS token.
    return blob.Uri + sasBlobToken;
}

Membuat AKUN SAS

Untuk membuat akun SAS untuk kontainer, panggil metode CloudStorageAccount.GetSharedAccessSignature.

Contoh kode berikut membuat SAS akun yang valid untuk layanan Blob dan File, serta memberikan klien izin untuk membaca, menulis, dan mendaftar untuk mengakses API di tingkat layanan. SAS akun membatasi protokol ke HTTPS, sehingga permintaan harus dibuat dengan HTTPS. Ingatlah untuk mengganti nilai placeholder dalam tanda kurung sudut dengan nilai Anda sendiri.

static string GetAccountSASToken()
{
    // To create the account SAS, you need to use Shared Key credentials. Modify for your account.
    const string ConnectionString = "DefaultEndpointsProtocol=https;AccountName=<storage-account>;AccountKey=<account-key>";
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);

    // Create a new access policy for the account.
    SharedAccessAccountPolicy policy = new SharedAccessAccountPolicy()
        {
            Permissions = SharedAccessAccountPermissions.Read | 
                          SharedAccessAccountPermissions.Write | 
                          SharedAccessAccountPermissions.List,
            Services = SharedAccessAccountServices.Blob | SharedAccessAccountServices.File,
            ResourceTypes = SharedAccessAccountResourceTypes.Service,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
            Protocols = SharedAccessProtocol.HttpsOnly
        };

    // Return the SAS token.
    return storageAccount.GetSharedAccessSignature(policy);
}

Menggunakan akun SAS dari klien

Dalam cuplikan ini, ganti placeholder <storage-account> dengan nama akun penyimpanan Anda.

static void UseAccountSAS(string sasToken)
{
    // Create new storage credentials using the SAS token.
    StorageCredentials accountSAS = new StorageCredentials(sasToken);
    // Use these credentials and the account name to create a Blob service client.
    CloudStorageAccount accountWithSAS = new CloudStorageAccount(accountSAS, "<storage-account>", endpointSuffix: null, useHttps: true);
    CloudBlobClient blobClientWithSAS = accountWithSAS.CreateCloudBlobClient();

    // Now set the service properties for the Blob client created with the SAS.
    blobClientWithSAS.SetServiceProperties(new ServiceProperties()
    {
        HourMetrics = new MetricsProperties()
        {
            MetricsLevel = MetricsLevel.ServiceAndApi,
            RetentionDays = 7,
            Version = "1.0"
        },
        MinuteMetrics = new MetricsProperties()
        {
            MetricsLevel = MetricsLevel.ServiceAndApi,
            RetentionDays = 7,
            Version = "1.0"
        },
        Logging = new LoggingProperties()
        {
            LoggingOperations = LoggingOperations.All,
            RetentionDays = 14,
            Version = "1.0"
        }
    });

    // The permissions granted by the account SAS also permit you to retrieve service properties.
    ServiceProperties serviceProperties = blobClientWithSAS.GetServiceProperties();
    Console.WriteLine(serviceProperties.HourMetrics.MetricsLevel);
    Console.WriteLine(serviceProperties.HourMetrics.RetentionDays);
    Console.WriteLine(serviceProperties.HourMetrics.Version);
}

Konkurensi optimis untuk blob

Contoh kode:

public void DemonstrateOptimisticConcurrencyBlob(string containerName, string blobName)
{
    Console.WriteLine("Demonstrate optimistic concurrency");

    // Parse connection string and create container.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExists();

    // Create test blob. The default strategy is last writer wins, so
    // write operation will overwrite existing blob if present.
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
    blockBlob.UploadText("Hello World!");

    // Retrieve the ETag from the newly created blob.
    string originalETag = blockBlob.Properties.ETag;
    Console.WriteLine("Blob added. Original ETag = {0}", originalETag);

    /// This code simulates an update by another client.
    string helloText = "Blob updated by another client.";
    // No ETag was provided, so original blob is overwritten and ETag updated.
    blockBlob.UploadText(helloText);
    Console.WriteLine("Blob updated. Updated ETag = {0}", blockBlob.Properties.ETag);

    // Now try to update the blob using the original ETag value.
    try
    {
        Console.WriteLine(@"Attempt to update blob using original ETag
                            to generate if-match access condition");
        blockBlob.UploadText(helloText, accessCondition: AccessCondition.GenerateIfMatchCondition(originalETag));
    }
    catch (StorageException ex)
    {
        if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
        {
            Console.WriteLine(@"Precondition failure as expected.
                                Blob's ETag does not match.");
        }
        else
        {
            throw;
        }
    }
    Console.WriteLine();
}

Konkurensi secara pesimis untuk objek biner besar

Contoh kode:

public void DemonstratePessimisticConcurrencyBlob(string containerName, string blobName)
{
    Console.WriteLine("Demonstrate pessimistic concurrency");

    // Parse connection string and create container.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExists();

    CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
    blockBlob.UploadText("Hello World!");
    Console.WriteLine("Blob added.");

    // Acquire lease for 15 seconds.
    string lease = blockBlob.AcquireLease(TimeSpan.FromSeconds(15), null);
    Console.WriteLine("Blob lease acquired. Lease = {0}", lease);

    // Update blob using lease. This operation should succeed.
    const string helloText = "Blob updated";
    var accessCondition = AccessCondition.GenerateLeaseCondition(lease);
    blockBlob.UploadText(helloText, accessCondition: accessCondition);
    Console.WriteLine("Blob updated using an exclusive lease");

    // Simulate another client attempting to update to blob without providing lease.
    try
    {
        // Operation will fail as no valid lease was provided.
        Console.WriteLine("Now try to update blob without valid lease.");
        blockBlob.UploadText("Update operation will fail without lease.");
    }
    catch (StorageException ex)
    {
        if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
        {
            Console.WriteLine(@"Precondition failure error as expected.
                                Blob lease not provided.");
        }
        else
        {
            throw;
        }
    }

    // Release lease proactively.
    blockBlob.ReleaseLease(accessCondition);
    Console.WriteLine();
}

Membangun aplikasi yang sangat tersedia dengan Blob Storage

Unduh contoh proyek, ekstrak (unzip) file storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.zip, lalu navigasikan ke folder v11 untuk menemukan file proyek.

Anda juga dapat menggunakan git untuk mengunduh salinan aplikasi ke lingkungan pengembangan Anda. Proyek sampel di folder v11 berisi aplikasi konsol.

git clone https://github.com/Azure-Samples/storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.git

Mengonfigurasi contoh

Dalam aplikasi, Anda harus menyediakan string koneksi untuk akun penyimpanan Anda. Anda dapat menyimpan string koneksi ini dalam variabel lingkungan pada komputer lokal yang menjalankan aplikasi. Ikuti salah satu contoh di bawah ini tergantung pada Sistem Operasi Anda untuk membuat variabel lingkungan.

Di portal Microsoft Azure, navigasikan ke akun penyimpanan Anda. Pilih Tombol Akses di bawah Pengaturan di akun penyimpanan Anda. Salin string koneksi dari kunci utama atau sekunder. Jalankan salah satu perintah berikut berdasarkan sistem operasi Anda, ganti <yourconnectionstring> dengan string koneksi Anda yang sebenarnya. Perintah ini menyimpan variabel lingkungan ke komputer lokal. Di Windows, variabel lingkungan tidak tersedia sampai Anda memuat ulang Command Prompt atau shell yang Anda gunakan.

Jalankan aplikasi konsol

Di Visual Studio, tekan F5 atau pilih Mulai untuk memulai debug aplikasi. Visual Studio secara otomatis memulihkan paket NuGet yang hilang jika pemulihan paket dikonfigurasi, kunjungi Menginstal dan menginstal ulang paket dengan pemulihan paket untuk mempelajari lebih lanjut.

Jendela konsol diluncurkan dan aplikasi mulai berjalan. Aplikasi mengunggah gambar HelloWorld.png dari solusi ke akun penyimpanan. Aplikasi memastikan gambar telah direplikasi ke titik akhir RA-GZRS sekunder. Kemudian mulai mengunduh gambar hingga 999 kali. Setiap bacaan diwakili oleh P atau S. Di mana P mewakili titik akhir utama dan S mewakili titik akhir sekunder.

Dalam kode sampel, tugas RunCircuitBreakerAsync dalam file Program.cs digunakan untuk mengunduh gambar dari akun penyimpanan menggunakan metode DownloadToFileAsync. Sebelum pengunduhan, OperationContext didefinisikan. Konteks operasi mendefinisikan penanganan aktivitas yang diaktifkan saat unduhan berhasil diselesaikan, atau jika unduhan gagal dan mencoba kembali.

Memahami kode sampel

Coba lagi penanganan aktivitas

Pemroses acara OperationContextRetrying dipanggil saat pengunduhan gambar gagal dan diatur untuk mengulang. Jika jumlah maksimum upaya ulang yang ditentukan dalam aplikasi tercapai, LocationMode permintaan diubah menjadi SecondaryOnly. Pengaturan ini memaksa aplikasi untuk mencoba mengunduh gambar dari titik akhir sekunder. Konfigurasi ini mengurangi waktu yang diperlukan untuk meminta gambar karena titik akhir utama tidak dicoba kembali tanpa batas waktu.

private static void OperationContextRetrying(object sender, RequestEventArgs e)
{
    retryCount++;
    Console.WriteLine("Retrying event because of failure reading the primary. RetryCount = " + retryCount);

    // Check if we have had more than n retries in which case switch to secondary.
    if (retryCount >= retryThreshold)
    {

        // Check to see if we can fail over to secondary.
        if (blobClient.DefaultRequestOptions.LocationMode != LocationMode.SecondaryOnly)
        {
            blobClient.DefaultRequestOptions.LocationMode = LocationMode.SecondaryOnly;
            retryCount = 0;
        }
        else
        {
            throw new ApplicationException("Both primary and secondary are unreachable. Check your application's network connection. ");
        }
    }
}

Meminta penanganan aktivitas yang selesai

Penanganan aktivitas OperationContextRequestCompleted dipanggil saat pengunduhan gambar berhasil. Jika aplikasi menggunakan titik akhir sekunder, aplikasi terus menggunakan titik akhir ini hingga 20 kali. Setelah 20 kali, aplikasi mengatur LocationMode kembali ke PrimaryThenSecondary dan mencoba kembali titik akhir utama. Jika permintaan berhasil, aplikasi terus membaca dari titik akhir utama.

private static void OperationContextRequestCompleted(object sender, RequestEventArgs e)
{
    if (blobClient.DefaultRequestOptions.LocationMode == LocationMode.SecondaryOnly)
    {
        // You're reading the secondary. Let it read the secondary [secondaryThreshold] times,
        //    then switch back to the primary and see if it's available now.
        secondaryReadCount++;
        if (secondaryReadCount >= secondaryThreshold)
        {
            blobClient.DefaultRequestOptions.LocationMode = LocationMode.PrimaryThenSecondary;
            secondaryReadCount = 0;
        }
    }
}

Mengunggah data acak dalam jumlah besar ke penyimpanan Azure

Jumlah utas minimum dan maksimum ditetapkan menjadi 100 untuk memastikan sejumlah besar koneksi bersamaan diizinkan.

private static async Task UploadFilesAsync()
{
    // Create five randomly named containers to store the uploaded files.
    CloudBlobContainer[] containers = await GetRandomContainersAsync();

    var currentdir = System.IO.Directory.GetCurrentDirectory();

    // Path to the directory to upload
    string uploadPath = currentdir + "\\upload";

    // Start a timer to measure how long it takes to upload all the files.
    Stopwatch time = Stopwatch.StartNew();

    try
    {
        Console.WriteLine("Iterating in directory: {0}", uploadPath);

        int count = 0;
        int max_outstanding = 100;
        int completed_count = 0;

        // Define the BlobRequestOptions on the upload.
        // This includes defining an exponential retry policy to ensure that failed connections
        // are retried with a back off policy. As multiple large files are being uploaded using
        // large block sizes, this can cause an issue if an exponential retry policy is not defined.
        // Additionally, parallel operations are enabled with a thread count of 8.
        // This should be a multiple of the number of processor cores in the machine.
        // Lastly, MD5 hash validation is disabled for this example, improving the upload speed.
        BlobRequestOptions options = new BlobRequestOptions
        {
            ParallelOperationThreadCount = 8,
            DisableContentMD5Validation = true,
            StoreBlobContentMD5 = false
        };

        // Create a new instance of the SemaphoreSlim class to 
        // define the number of threads to use in the application.
        SemaphoreSlim sem = new SemaphoreSlim(max_outstanding, max_outstanding);

        List<Task> tasks = new List<Task>();
        Console.WriteLine("Found {0} file(s)", Directory.GetFiles(uploadPath).Count());

        // Iterate through the files
        foreach (string path in Directory.GetFiles(uploadPath))
        {
            var container = containers[count % 5];
            string fileName = Path.GetFileName(path);
            Console.WriteLine("Uploading {0} to container {1}", path, container.Name);
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            // Set the block size to 100MB.
            blockBlob.StreamWriteSizeInBytes = 100 * 1024 * 1024;

            await sem.WaitAsync();

            // Create a task for each file to upload. The tasks are
            // added to a collection and all run asynchronously.
            tasks.Add(blockBlob.UploadFromFileAsync(path, null, options, null).ContinueWith((t) =>
            {
                sem.Release();
                Interlocked.Increment(ref completed_count);
            }));

            count++;
        }

        // Run all the tasks asynchronously.
        await Task.WhenAll(tasks);

        time.Stop();

        Console.WriteLine("Upload has been completed in {0} seconds. Press any key to continue", time.Elapsed.TotalSeconds.ToString());

        Console.ReadLine();
    }
    catch (DirectoryNotFoundException ex)
    {
        Console.WriteLine("Error parsing files in the directory: {0}", ex.Message);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Selain mengatur pengaturan threading dan batas koneksi, BlobRequestOptions untuk metode UploadFromStreamAsync dikonfigurasi untuk menggunakan paralelisme dan menonaktifkan validasi hash MD5. File diunggah dalam blok 100 mb, konfigurasi ini memberikan performa yang lebih baik tetapi bisa mahal jika menggunakan jaringan berkinerja buruk seolah-olah ada kegagalan seluruh blok 100 mb dicoba kembali.

Harta benda Nilai Deskripsi
ParallelOperationThreadCount 8 Pengaturan memecah blob menjadi blok saat mengunggah. Untuk performa tertinggi, nilai ini harus delapan kali lipat dari jumlah inti.
DisableContentMD5Validation Menonaktifkan Validasi MD5 Konten benar Properti ini menonaktifkan pemeriksaan hash MD5 dari konten yang diunggah. Menonaktifkan validasi MD5 menghasilkan transfer yang lebih cepat. Tetapi tidak mengonfirmasi validitas atau integritas file yang sedang ditransfer.
StoreBlobContentMD5 palsu Properti ini menentukan apakah hash MD5 dihitung dan disimpan dalam file.
RetryPolicy Backoff 2 detik dan 10 percobaan ulang maksimal Menentukan kebijakan pengulangan permintaan. Kegagalan koneksi dicoba kembali, dalam contoh ini kebijakan ExponentialRetry dikonfigurasi dengan backoff 2 detik, dan jumlah coba lagi maksimum 10. Pengaturan ini penting ketika aplikasi Anda mendekati target skalabilitas untuk penyimpanan Blob. Selengkapnya, lihat Skalabilitas dan target performa untuk penyimpanan Blob.

Mengunduh sejumlah besar data acak dari Azure Storage

Aplikasi membaca kontainer yang terletak di akun penyimpanan yang ditentukan dalam storageconnectionstring. Ini melakukan iterasi melalui blob 10 sekaligus menggunakan metode ListBlobsSegmentedAsync dalam kontainer dan mengunduhnya ke komputer lokal menggunakan metode DownloadToFileAsync.

Tabel berikut menunjukkan BlobRequestOptions yang ditentukan untuk setiap blob saat diunduh.

Harta benda Nilai Deskripsi
DisableContentMD5Validation benar Properti ini menonaktifkan pemeriksaan hash MD5 dari konten yang diunggah. Menonaktifkan validasi MD5 menghasilkan transfer yang lebih cepat. Tetapi tidak mengonfirmasi validitas atau integritas file yang sedang ditransfer.
StoreBlobContentMD5 palsu Properti ini menentukan apakah hash MD5 dihitung dan disimpan.
private static async Task DownloadFilesAsync()
{
    CloudBlobClient blobClient = GetCloudBlobClient();

    // Define the BlobRequestOptions on the download, including disabling MD5 
    // hash validation for this example, this improves the download speed.
    BlobRequestOptions options = new BlobRequestOptions
    {
        DisableContentMD5Validation = true,
        StoreBlobContentMD5 = false
    };

    // Retrieve the list of containers in the storage account.
    // Create a directory and configure variables for use later.
    BlobContinuationToken continuationToken = null;
    List<CloudBlobContainer> containers = new List<CloudBlobContainer>();
    do
    {
        var listingResult = await blobClient.ListContainersSegmentedAsync(continuationToken);
        continuationToken = listingResult.ContinuationToken;
        containers.AddRange(listingResult.Results);
    }
    while (continuationToken != null);

    var directory = Directory.CreateDirectory("download");
    BlobResultSegment resultSegment = null;
    Stopwatch time = Stopwatch.StartNew();

    // Download the blobs
    try
    {
        List<Task> tasks = new List<Task>();
        int max_outstanding = 100;
        int completed_count = 0;

        // Create a new instance of the SemaphoreSlim class to
        // define the number of threads to use in the application.
        SemaphoreSlim sem = new SemaphoreSlim(max_outstanding, max_outstanding);

        // Iterate through the containers
        foreach (CloudBlobContainer container in containers)
        {
            do
            {
                // Return the blobs from the container, 10 at a time.
                resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, 10, continuationToken, null, null);
                continuationToken = resultSegment.ContinuationToken;
                {
                    foreach (var blobItem in resultSegment.Results)
                    {

                        if (((CloudBlob)blobItem).Properties.BlobType == BlobType.BlockBlob)
                        {
                            // Get the blob and add a task to download the blob asynchronously from the storage account.
                            CloudBlockBlob blockBlob = container.GetBlockBlobReference(((CloudBlockBlob)blobItem).Name);
                            Console.WriteLine("Downloading {0} from container {1}", blockBlob.Name, container.Name);
                            await sem.WaitAsync();
                            tasks.Add(blockBlob.DownloadToFileAsync(directory.FullName + "\\" + blockBlob.Name, FileMode.Create, null, options, null).ContinueWith((t) =>
                            {
                                sem.Release();
                                Interlocked.Increment(ref completed_count);
                            }));

                        }
                    }
                }
            }
            while (continuationToken != null);
        }

        // Creates an asynchronous task that completes when all the downloads complete.
        await Task.WhenAll(tasks);
    }
    catch (Exception e)
    {
        Console.WriteLine("\nError encountered during transfer: {0}", e.Message);
    }

    time.Stop();
    Console.WriteLine("Download has been completed in {0} seconds. Press any key to continue", time.Elapsed.TotalSeconds.ToString());
    Console.ReadLine();
}

Mengaktifkan fitur log Azure Storage Analytics (klasik)

Contoh kode:

var storageAccount = CloudStorageAccount.Parse(connStr);  
var queueClient = storageAccount.CreateCloudQueueClient();  
var serviceProperties = queueClient.GetServiceProperties();

serviceProperties.Logging.LoggingOperations = LoggingOperations.All;  
serviceProperties.Logging.RetentionDays = 2;

queueClient.SetServiceProperties(serviceProperties);  

Mengubah periode penyimpanan data catatan

Contoh berikut menampilkan masa retensi untuk layanan penyimpanan data blob dan antrean di konsol.

var storageAccount = CloudStorageAccount.Parse(connectionString);

var blobClient = storageAccount.CreateCloudBlobClient();
var queueClient = storageAccount.CreateCloudQueueClient();

var blobserviceProperties = blobClient.GetServiceProperties();
var queueserviceProperties = queueClient.GetServiceProperties();

Console.WriteLine("Retention period for logs from the blob service is: " +
   blobserviceProperties.Logging.RetentionDays.ToString());

Console.WriteLine("Retention period for logs from the queue service is: " +
   queueserviceProperties.Logging.RetentionDays.ToString());

Contoh berikut mengubah masa retensi log untuk layanan penyimpanan blob dan antrean menjadi 4 hari.


blobserviceProperties.Logging.RetentionDays = 4;
queueserviceProperties.Logging.RetentionDays = 4;

blobClient.SetServiceProperties(blobserviceProperties);
queueClient.SetServiceProperties(queueserviceProperties);  

Mengaktifkan metrik Azure Storage Analytics (klasik)

Contoh kode:

var storageAccount = CloudStorageAccount.Parse(connStr);  
var queueClient = storageAccount.CreateCloudQueueClient();  
var serviceProperties = queueClient.GetServiceProperties();

serviceProperties.HourMetrics.MetricsLevel = MetricsLevel.Service;  
serviceProperties.HourMetrics.RetentionDays = 10;

queueClient.SetServiceProperties(serviceProperties);  

Mengonfigurasi Keamanan Lapisan Transportasi (TLS) untuk aplikasi klien

Contoh berikut menunjukkan cara mengaktifkan TLS 1.2 di klien .NET menggunakan versi 11.x dari pustaka klien Azure Storage:

static void EnableTls12()
{
    // Enable TLS 1.2 before connecting to Azure Storage
    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

    // Add your connection string here.
    string connectionString = "";

    // Connect to Azure Storage and create a new container.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    CloudBlobContainer container = blobClient.GetContainerReference("sample-container");
    container.CreateIfNotExists();
}

Memantau, mendiagnosis, dan memecahkan masalah Microsoft Azure Storage (klasik)

Jika Pustaka Klien Penyimpanan melempar StorageException di klien, properti RequestInformation berisi objek RequestResult yang menyertakan properti ServiceRequestID. Anda juga dapat mengakses RequestResult object dari instance OperationContext.

Sampel kode di bawah ini menunjukkan cara mengatur nilai ClientRequestId kustom dengan melampirkan objek OperationContext ke permintaan layanan penyimpanan. Ini juga menunjukkan cara mengambil nilai ServerRequestId dari pesan respons.

//Parse the connection string for the storage account.
const string ConnectionString = "DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

// Create an Operation Context that includes custom ClientRequestId string based on constants defined within the application along with a Guid.
OperationContext oc = new OperationContext();
oc.ClientRequestID = String.Format("{0} {1} {2} {3}", HOSTNAME, APPNAME, USERID, Guid.NewGuid().ToString());

try
{
    CloudBlobContainer container = blobClient.GetContainerReference("democontainer");
    ICloudBlob blob = container.GetBlobReferenceFromServer("testImage.jpg", null, null, oc);  
    var downloadToPath = string.Format("./{0}", blob.Name);
    using (var fs = File.OpenWrite(downloadToPath))
    {
        blob.DownloadToStream(fs, null, null, oc);
        Console.WriteLine("\t Blob downloaded to file: {0}", downloadToPath);
    }
}
catch (StorageException storageException)
{
    Console.WriteLine("Storage exception {0} occurred", storageException.Message);
    // Multiple results may exist due to client side retry logic - each retried operation will have a unique ServiceRequestId
    foreach (var result in oc.RequestResults)
    {
            Console.WriteLine("HttpStatus: {0}, ServiceRequestId {1}", result.HttpStatusCode, result.ServiceRequestID);
    }
}

Menyelidiki masalah performa klien - nonaktifkan algoritma Nagle

Contoh kode:

var storageAccount = CloudStorageAccount.Parse(connStr);
ServicePoint queueServicePoint = ServicePointManager.FindServicePoint(storageAccount.QueueEndpoint);
queueServicePoint.UseNagleAlgorithm = false;

Menyelidiki masalah latensi jaringan - mengonfigurasi Berbagi Sumber Daya Lintas Asal (CORS)

Contoh kode:

CloudBlobClient client = new CloudBlobClient(blobEndpoint, new StorageCredentials(accountName, accountKey));
// Set the service properties.
ServiceProperties sp = client.GetServiceProperties();
sp.DefaultServiceVersion = "2013-08-15";
CorsRule cr = new CorsRule();
cr.AllowedHeaders.Add("*");
cr.AllowedMethods = CorsHttpMethods.Get | CorsHttpMethods.Put;
cr.AllowedOrigins.Add("http://www.contoso.com");
cr.ExposedHeaders.Add("x-ms-*");
cr.MaxAgeInSeconds = 5;
sp.Cors.CorsRules.Clear();
sp.Cors.CorsRules.Add(cr);
client.SetServiceProperties(sp);

Membuat blob halaman kosong dengan ukuran yang ditentukan

Untuk membuat blob halaman, pertama-tama kita membuat objek CloudBlobClient, dengan URI dasar untuk mengakses penyimpanan blob untuk akun penyimpanan Anda (pbaccount pada gambar 1) bersama dengan objek StorageCredentialsAccountAndKey, seperti yang ditunjukkan dalam contoh berikut. Contoh kemudian menunjukkan pembuatan referensi ke objek CloudBlobContainer, lalu membuat kontainer (testvhds) jika belum ada. Kemudian menggunakan objek CloudBlobContainer, buat referensi ke objek CloudPageBlob dengan menentukan nama blob halaman (os4.vhd) untuk diakses. Untuk membuat blob halaman, panggil CloudPageBlob.Create, dengan menentukan ukuran maksimum untuk blob yang akan dibuat. blobSize harus merupakan kelipatan 512 byte.

using Microsoft.Azure;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;

long OneGigabyteAsBytes = 1024 * 1024 * 1024;
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference("testvhds");

// Create the container if it doesn't already exist.
container.CreateIfNotExists();

CloudPageBlob pageBlob = container.GetPageBlobReference("os4.vhd");
pageBlob.Create(16 * OneGigabyteAsBytes);

Mengubah ukuran blob halaman

Untuk mengubah ukuran blob halaman setelah pembuatan, gunakan metode Mengubah Ukuran. Ukuran yang diminta harus merupakan kelipatan dari 512 bita.

pageBlob.Resize(32 * OneGigabyteAsBytes);

Menyimpan halaman ke dalam blob halaman

Untuk menulis halaman, gunakan metode CloudPageBlob.WritePages.

pageBlob.WritePages(dataStream, startingOffset); 

Membaca data halaman dari blob halaman

Untuk membaca halaman, gunakan metode CloudPageBlob.DownloadRangeToByteArray untuk membaca rentang byte dari blob halaman.

byte[] buffer = new byte[rangeSize];
pageBlob.DownloadRangeToByteArray(buffer, bufferOffset, pageBlobOffset, rangeSize); 

Untuk menentukan halaman mana yang didukung oleh data, gunakan CloudPageBlob.GetPageRanges. Anda kemudian dapat menghitung rentang yang dikembalikan dan mengunduh data di setiap rentang.

IEnumerable<PageRange> pageRanges = pageBlob.GetPageRanges();

foreach (PageRange range in pageRanges)
{
    // Calculate the range size
    int rangeSize = (int)(range.EndOffset + 1 - range.StartOffset);

    byte[] buffer = new byte[rangeSize];

    // Read from the correct starting offset in the page blob and
    // place the data in the bufferOffset of the buffer byte array
    pageBlob.DownloadRangeToByteArray(buffer, bufferOffset, range.StartOffset, rangeSize);

    // Then use the buffer for the page range just read
}