kódminták Azure Blob Storage .NET 11.x-es verziójú ügyfélkódtárak használatával
Ez a cikk a .NET-hez készült Azure Blob Storage ügyfélkódtár 11.x verzióját használó kódmintákat mutatja be.
2023. március 31-én megszüntettük az Azure SDK-kódtárak támogatását, amelyek nem felelnek meg az Azure SDK jelenlegi irányelveinek. Az új Azure SDK-kódtárakat rendszeresen frissítjük, hogy egységes élményeket teremtsen, és megerősítse a biztonsági helyzetét. Javasoljuk, hogy térjen át az új Azure SDK-kódtárakra, hogy kihasználhassa az új képességeket és a kritikus biztonsági frissítéseket.
Bár a régebbi kódtárak 2023. március 31-e után is használhatók, a Továbbiakban nem kapnak hivatalos támogatást és frissítéseket a Microsofttól. További információt a támogatási kivezetésről szóló közleményben talál.
Pillanatkép Létrehozás
Ha a .NET-hez készült Azure Storage ügyfélkódtár 11.x verziójával szeretne pillanatképet készíteni egy blokkblobról, használja az alábbi módszerek egyikét:
Az alábbi példakód bemutatja, hogyan hozhat létre pillanatképet a 11.x verzióval. Ez a példa további metaadatokat ad meg a pillanatképhez a létrehozáskor.
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;
}
}
Pillanatképek törlése
Ha törölni szeretne egy blobot és annak pillanatképeit a .NET-hez készült Azure Storage ügyfélkódtár 11.x verziójával, használja az alábbi blobtörlési módszerek egyikét, és adja meg a DeleteSnapshotsOption enumerálást :
Az alábbi példakód bemutatja, hogyan törölhet egy blobot és annak pillanatképeit a .NET-ben, ahol blockBlob
egy [CloudBlockBlob][dotnet_CloudBlockBlob] típusú objektum található:
await blockBlob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots, null, null, null);
Tárolt hozzáférési szabályzat Létrehozás
Ha tárolt hozzáférési szabályzatot szeretne létrehozni egy tárolón az Azure Storage .NET-ügyfélkódtárának 11.x verziójával, hívja meg az alábbi módszerek egyikét:
Az alábbi példa egy olyan tárolt hozzáférési szabályzatot hoz létre, amely egy napig érvényes, és olvasási, írási és listázási engedélyeket biztosít:
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);
}
Szolgáltatás SAS-Létrehozás blobtárolóhoz
Ha szolgáltatás SAS-t szeretne létrehozni egy tárolóhoz, hívja meg a CloudBlobContainer.GetSharedAccessSignature metódust .
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;
}
Szolgáltatás SAS-Létrehozás blobhoz
Ha szolgáltatás SAS-t szeretne létrehozni egy blobhoz, hívja meg a CloudBlob.GetSharedAccessSignature metódust .
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;
}
Fiók SAS létrehozása
Ha fiók SAS-t szeretne létrehozni egy tárolóhoz, hívja meg a CloudStorageAccount.GetSharedAccessSignature metódust .
Az alábbi példakód létrehoz egy fiók SAS-t, amely érvényes a Blob- és Fájlszolgáltatásokhoz, és olvasási, írási és listázási engedélyeket ad az ügyfélnek a szolgáltatásszintű API-k eléréséhez. A fiók sasa HTTPS-ra korlátozza a protokollt, ezért a kérést HTTPS-lel kell elvégezni. Ne felejtse el lecserélni a szögletes zárójelek helyőrző értékeit a saját értékeire:
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);
}
Ügyfél fiók SAS-ének használata
Ebben a kódrészletben cserélje le a <storage-account>
helyőrzőt a tárfiók nevére.
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);
}
Optimista egyidejűség a blobok esetében
Példa kódra:
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();
}
Pesszimista egyidejűség a blobok esetében
Példa kódra:
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();
}
Magas rendelkezésre állású alkalmazás létrehozása a Blob Storage használatával
Töltse le a mintaprojektet, bontsa ki (bontsa ki) a storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.zip fájlt, majd keresse meg a v11 mappát a projektfájlok megkereséséhez.
A git használatával is letöltheti az alkalmazás egy másolatát a fejlesztői környezetbe. A v11 mappában található mintaprojekt egy konzolalkalmazást tartalmaz.
git clone https://github.com/Azure-Samples/storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.git
A minta konfigurálása
Az alkalmazásban meg kell adnia a tárfiókjához tartozó kapcsolati sztringet. Ezt a kapcsolati sztringet tárolhatja egy környezeti változóban az alkalmazást futtató helyi gépen. A környezeti változó létrehozásához kövesse az alábbi példák egyikét az operációs rendszerének megfelelően.
Az Azure Portalon lépjen a tárfiókra. Válassza a Hozzáférési kulcsok lehetőséget a tárfiók Beállítások területén. Másolja ki az elsődleges vagy a másodlagos kulcs kapcsolati sztringjét. Futtassa az alábbi parancsok egyikét az operációs rendszer alapján, és cserélje le <a kapcsolati sztringet> a tényleges kapcsolati karakterlánc. A parancs egy környezeti változót ment a helyi számítógépen. A Windowsban a környezeti változó nem érhető el, amíg újra be nem tölti a használt parancssort vagy rendszerhéjat.
A konzolalkalmazás futtatása
A Visual Studióban nyomja le az F5 billentyűt , vagy kattintson a Start gombra az alkalmazás hibakeresésének megkezdéséhez. A Visual Studio automatikusan visszaállítja a hiányzó NuGet-csomagokat, ha a csomag-visszaállítás konfigurálva van. További információt a Csomagok telepítése és újratelepítése csomag-visszaállítással című témakörben talál.
Megnyílik a konzolablak, és az alkalmazás futni kezd. Az alkalmazás feltölti a HelloWorld.png képet a megoldásból a tárfiókra. Az alkalmazás ellenőrzi, hogy a rendszerkép replikálva lett-e a másodlagos RA-GZRS végpontra. Ezután elkezdi letölteni a képet legfeljebb 999 alkalommal. Minden olvasást egy P vagy egy S jelöl. Ahol a P az elsődleges végpontot, az S pedig a másodlagos végpontot jelöli.
A mintakód a Program.cs
fájlban található RunCircuitBreakerAsync
művelettel letölt egy képet a tárfiókból a DownloadToFileAsync metódus segítségével. A letöltés előtt meg kell határozni egy OperationContext környezetet. A műveleti környezet olyan eseménykezelőket határoz meg, amelyek akkor aktiválódnak, ha a letöltés sikeresen befejeződik, vagy ha egy letöltés meghiúsul, és újra próbálkozik.
A mintakód értelmezése
Újrapróbálkozási eseménykezelő
A rendszer akkor hívja meg az OperationContextRetrying
eseménykezelőt, ha a kép letöltése meghiúsult, és újrapróbálkozásra van beállítva. Ha a rendszer elérte a próbálkozások alkalmazásban definiált maximális számát, a kérelem LocationMode paramétere SecondaryOnly
értékre változik. Ez a beállítás kényszeríti az alkalmazást, hogy a másodlagos végpontról kísérelje meg letölteni a képet. Ez a konfiguráció csökkenti a rendszerkép kéréséhez szükséges időt, mivel az elsődleges végpontot nem próbálkozik meg határozatlan ideig.
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. ");
}
}
}
Befejezett kérelem eseménykezelő
A rendszer akkor hívja meg az OperationContextRequestCompleted
eseménykezelőt, ha a kép letöltése sikerült. Ha az alkalmazás a másodlagos végpontot használja, továbbra is ezt a végpontot használja majd legfeljebb 20 alkalommal. A 20. alkalom után az alkalmazás visszaállítja a LocationMode paramétert PrimaryThenSecondary
értékre, és az elsődleges végponton próbálkozik újra. Ha a kérelem sikeres, az alkalmazás továbbra is az elsődleges végpontról végzi a beolvasást.
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;
}
}
}
Nagy mennyiségű véletlenszerű adat feltöltése az Azure Storage-ba
A szálak minimális és maximális száma 100-ra van állítva, hogy nagy számú egyidejű kapcsolat legyen engedélyezve.
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);
}
}
A szálkezelési és a kapcsolati korlátozások beállításán felül az UploadFromStreamAsync metódus BlobRequestOptions beállítása úgy van konfigurálva, hogy párhuzamosságot használjon és letiltsa az MD5-kivonat érvényesítését. A fájlok feltöltése 100 MB méretű blokkokban történik. Ez a konfiguráció jobb teljesítményt biztosít, a használata azonban gyengén teljesítő hálózaton nem ajánlott, mert hiba esetén a teljes 100 MB-os blokk feltöltését újra kell kezdeni.
Tulajdonság | Érték | Leírás |
---|---|---|
ParallelOperationThreadCount | 8 | A beállítás feltöltéskor blokkokra töri a blobot. A legnagyobb teljesítmény érdekében ennek az értéknek a magok számának nyolcszorosának kell lennie. |
DisableContentMD5Validation | true | Ez a tulajdonság letiltja a feltöltött tartalom MD5-kivonat ellenőrzését. A gyorsabb átvitel érdekében tiltsa le az MD5-ellenőrzést. Így azonban nem biztosított a folyamatban lévő átvitelben érintett fájlok érvényessége vagy integritása. |
StoreBlobContentMD5 | hamis | Ez a tulajdonság határozza meg, hogy az MD5 kivonatoló kiszámítása és fájlban való tárolása megtörtént-e. |
RetryPolicy | 2-second backoff with 10 max retry | A kérések újrapróbálkozási szabályzatát határozza meg. Kapcsolódási hiba esetén a rendszer újra próbálkozik, ebben a példában az ExponentialRetry szabályzat 2 másodperces leállításra és legfeljebb 10 újrapróbálkozásra van konfigurálva. Ez a beállítás akkor fontos, ha az alkalmazás megközelíti a Blob Storage skálázhatósági céljait. További információ: A Blob Storage méretezhetőségi és teljesítménycéljai. |
Nagy mennyiségű véletlenszerű adat letöltése az Azure Storage-ból
Az alkalmazás a storageconnectionstring karakterlánccal megadott tárfiókban lévő tárolókat olvassa. A tárolókban a ListBlobsSegmentedAsync metódussal végigvezeti a 10-et a blobokon, és letölti őket a helyi gépre a DownloadToFileAsync metódussal.
Az alábbi táblázat az egyes blobokhoz a letöltés során definiált BlobRequestOptions elemet mutatja be.
Tulajdonság | Érték | Leírás |
---|---|---|
DisableContentMD5Validation | true | Ez a tulajdonság letiltja a feltöltött tartalom MD5-kivonat ellenőrzését. A gyorsabb átvitel érdekében tiltsa le az MD5-ellenőrzést. Így azonban nem biztosított a folyamatban lévő átvitelben érintett fájlok érvényessége vagy integritása. |
StoreBlobContentMD5 | hamis | Ez a tulajdonság határozza meg, hogy az MD5 kivonatoló kiszámítása és tárolása megtörtént-e. |
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();
}
Azure Storage Analytics-naplók engedélyezése (klasszikus)
Példa kódra:
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);
A naplók adatmegőrzési időtartamának módosítása
Az alábbi példa a blob- és üzenetsortár-szolgáltatások megőrzési időtartamát nyomtatja ki a konzolra.
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());
Az alábbi példa a blob- és üzenetsortár-szolgáltatások naplóinak megőrzési időtartamát 4 napra módosítja.
blobserviceProperties.Logging.RetentionDays = 4;
queueserviceProperties.Logging.RetentionDays = 4;
blobClient.SetServiceProperties(blobserviceProperties);
queueClient.SetServiceProperties(queueserviceProperties);
Azure Storage Analytics-metrikák engedélyezése (klasszikus)
Példa kódra:
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);
Transport Layer Security (TLS) konfigurálása ügyfélalkalmazáshoz
Az alábbi minta bemutatja, hogyan engedélyezheti a TLS 1.2-t egy .NET-ügyfélen az Azure Storage-ügyfélkódtár 11.x verziójával:
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();
}
Microsoft Azure Storage monitorozása, diagnosztizálása és hibaelhárítása (klasszikus)
Ha a Storage-ügyfélkódtár StorageException kivételt ad az ügyfélhez, a RequestInformation tulajdonság tartalmaz egy RequestResult objektumot, amely tartalmaz egy ServiceRequestID tulajdonságot . RequestResult objektumot is elérhet egy OperationContext-példányból.
Az alábbi kódminta bemutatja, hogyan állíthat be egyéni ClientRequestId értéket úgy, hogy csatol egy OperationContext objektumot a storage szolgáltatáshoz. Azt is bemutatja, hogyan kérhető le a ServerRequestId érték a válaszüzenetből.
//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);
}
}
Ügyfélteljesítmény-problémák vizsgálata – a Nagle-algoritmus letiltása
Példa kódra:
var storageAccount = CloudStorageAccount.Parse(connStr);
ServicePoint queueServicePoint = ServicePointManager.FindServicePoint(storageAccount.QueueEndpoint);
queueServicePoint.UseNagleAlgorithm = false;
Hálózati késéssel kapcsolatos problémák vizsgálata – eltérő eredetű erőforrások megosztásának konfigurálása (CORS)
Példa kódra:
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);
Megadott méretű üres lapblob létrehozása
Lapblob létrehozásához először létrehozunk egy CloudBlobClient objektumot a tárfiók blobtárolójának eléréséhez szükséges alap URI-val (pbaccount az 1. ábrán) a StorageCredentialsAccountAndKey objektummal együtt, az alábbi példában látható módon. A példa ezután egy CloudBlobContainer objektumra mutató hivatkozás létrehozását, majd a tároló (testvhds) létrehozását mutatja be, ha még nem létezik. Ezután a CloudBlobContainer objektummal hozzon létre egy CloudPageBlob objektumra mutató hivatkozást a lapblob nevének (os4.vhd) megadásával. A lapblob létrehozásához hívja meg a CloudPageBlob.Létrehozás, és adja meg a blob létrehozásához szükséges maximális méretet. A blobSize értéknek 512 bájt többszörösének kell lennie.
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);
Lapblob átméretezése
A lapblobok létrehozás utáni átméretezéséhez használja az Átméretezés metódust. A kért méretnek 512 bájt többszörösének kell lennie.
pageBlob.Resize(32 * OneGigabyteAsBytes);
Lapok írása lapblobba
Oldalak írásához használja a CloudPageBlob.WritePages metódust .
pageBlob.WritePages(dataStream, startingOffset);
Lapok olvasása lapblobból
A lapok olvasásához használja a CloudPageBlob.DownloadRangeToByteArray metódust a lapblob bájttartományának beolvasásához.
byte[] buffer = new byte[rangeSize];
pageBlob.DownloadRangeToByteArray(buffer, bufferOffset, pageBlobOffset, rangeSize);
A CloudPageBlob.GetPageRanges használatával állapíthatja meg, hogy mely lapokról készít biztonsági másolatot az adatok. Ezután enumerálhatja a visszaadott tartományokat, és letöltheti az adatokat az egyes tartományokból.
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
}