/// <summary> /// Releases the blob resources used by the stream. /// </summary> public void Dispose() { if (this.originalStream != null) { this.originalStream.Dispose(); this.originalStream = null; } }
/// <summary> /// Initializes a new instance of the BlobWriteStream class for a block blob. /// </summary> /// <param name="blockBlob">Blob reference to write to.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <param name="transform">The ICryptoTransform function for the request.</param> internal BlobEncryptedWriteStream(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, ICryptoTransform transform) { CommonUtility.AssertNotNull("transform", transform); if (options.EncryptionPolicy.EncryptionMode != BlobEncryptionMode.FullBlob) { throw new InvalidOperationException(SR.InvalidEncryptionMode, null); } // Since this is done on the copy of the options object that the client lib maintains and not on the user's options object and is done after getting // the transform function, it should be fine. Setting this ensures that an error is not thrown when PutBlock is called internally from the write method on the stream. options.SkipEncryptionPolicyValidation = true; this.transform = transform; this.writeStream = new BlobWriteStream(blockBlob, accessCondition, options, operationContext) { IgnoreFlush = true }; this.cryptoStream = new CryptoStream(this.writeStream, transform, CryptoStreamMode.Write); }
/// <summary> /// Initializes a new instance of the BlobWriteStream class for a page blob. /// </summary> /// <param name="pageBlob">Blob reference to write to.</param> /// <param name="pageBlobSize">Size of the page blob.</param> /// <param name="createNew">Use <c>true</c> if the page blob is newly created, <c>false</c> otherwise.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <param name="transform">The ICryptoTransform function for the request.</param> internal BlobEncryptedWriteStream(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, ICryptoTransform transform) { CommonUtility.AssertNotNull("transform", transform); if (options.EncryptionPolicy.EncryptionMode != BlobEncryptionMode.FullBlob) { throw new InvalidOperationException(SR.InvalidEncryptionMode, null); } // Since this is done on the copy of the options object that the client lib maintains and not on the user's options object and is done after getting // the transform function, it should be fine. Setting this ensures that an error is not thrown when PutPage is called internally from the write method on the stream. options.SkipEncryptionPolicyValidation = true; this.transform = transform; this.writeStream = new BlobWriteStream(pageBlob, pageBlobSize, createNew, accessCondition, options, operationContext) { IgnoreFlush = true }; this.cryptoStream = new CryptoStream(this.writeStream, transform, CryptoStreamMode.Write); }
public virtual Task<CloudBlobStream> OpenWriteAsync(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) { this.attributes.AssertNoSnapshot(); bool createNew = size.HasValue; BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient, false); if (!createNew && modifiedOptions.StoreBlobContentMD5.Value) { throw new ArgumentException(SR.MD5NotPossible); } return Task.Run(async () => { if (createNew) { await this.CreateAsync(size.Value, accessCondition, options, operationContext, cancellationToken); } else { await this.FetchAttributesAsync(accessCondition, options, operationContext, cancellationToken); size = this.Properties.Length; } if (accessCondition != null) { accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); } CloudBlobStream stream = new BlobWriteStream(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); return stream; }, cancellationToken); }
public IAsyncOperation<ICloudBlobStream> OpenWriteAsync(bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) #endif { this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.AppendBlob, this.ServiceClient, false); if (!createNew && modifiedOptions.StoreBlobContentMD5.Value) { throw new ArgumentException(SR.MD5NotPossible); } #if ASPNET_K || PORTABLE return Task.Run(async () => #else return AsyncInfo.Run(async (token) => #endif { if (createNew) { #if ASPNET_K || PORTABLE await this.CreateOrReplaceAsync(accessCondition, options, operationContext, cancellationToken); #else await this.CreateOrReplaceAsync(accessCondition, options, operationContext).AsTask(token); #endif } else { // Although we don't need any properties from the service, we should make this call in order to honor the user specified conditional headers // while opening an existing stream and to get the append position for an existing blob if user didn't specify one. #if ASPNET_K || PORTABLE await this.FetchAttributesAsync(accessCondition, options, operationContext, cancellationToken); #else await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); #endif } if (accessCondition != null) { accessCondition = new AccessCondition() { LeaseId = accessCondition.LeaseId, IfAppendPositionEqual = accessCondition.IfAppendPositionEqual, IfMaxSizeLessThanOrEqual = accessCondition.IfMaxSizeLessThanOrEqual }; } #if ASPNET_K || PORTABLE CloudBlobStream stream = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); #else ICloudBlobStream stream = new BlobWriteStreamHelper(this, accessCondition, modifiedOptions, operationContext); #endif return stream; #if ASPNET_K || PORTABLE }, cancellationToken); #else });
/// <summary> /// Opens a stream for writing to the blob. /// </summary> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <returns>A stream to be used for writing to the blob.</returns> public IAsyncOperation<IOutputStream> OpenWriteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) { this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); if ((accessCondition != null) && accessCondition.IsConditional) { return AsyncInfo.Run(async (token) => { try { await this.FetchAttributesAsync(accessCondition, modifiedOptions, operationContext); } catch (Exception) { if ((operationContext.LastResult != null) && (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) && string.IsNullOrEmpty(accessCondition.IfMatchETag)) { // If we got a 404 and the condition was not an If-Match, // we should continue with the operation. } else { throw; } } return new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext).AsOutputStream(); }); } else { IOutputStream stream = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext).AsOutputStream(); return Task.FromResult(stream).AsAsyncOperation(); } }
/// <summary> /// Initializes a new instance of the BlobWriteStreamHelper class for an append blob. /// </summary> /// <param name="appendBlob">Blob reference to write to.</param> /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param> /// <param name="options">An object that specifies additional options for the request.</param> internal BlobWriteStreamHelper(CloudAppendBlob appendBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) { this.originalStream = new BlobWriteStream(appendBlob, accessCondition, options, operationContext); this.originalStreamAsOutputStream = this.originalStream.AsOutputStream(); }
/// <summary> /// Initializes a new instance of the BlobWriteStreamHelper class for a page blob. /// </summary> /// <param name="pageBlob">Blob reference to write to.</param> /// <param name="pageBlobSize">Size of the page blob.</param> /// <param name="createNew">Use <c>true</c> if the page blob is newly created, <c>false</c> otherwise.</param> /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param> /// <param name="options">An object that specifies additional options for the request.</param> internal BlobWriteStreamHelper(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) { this.originalStream = new BlobWriteStream(pageBlob, pageBlobSize, createNew, accessCondition, options, operationContext); this.originalStreamAsOutputStream = this.originalStream.AsOutputStream(); }
/// <summary> /// Opens a stream for writing to the blob. If the blob already exists, it will be overwritten. /// </summary> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for a task to complete.</param> /// <returns>A stream to be used for writing to the blob.</returns> /// <remarks> /// <para>Note that this method always makes a call to the <see cref="CloudBlob.FetchAttributesAsync(AccessCondition, BlobRequestOptions, OperationContext, CancellationToken)"/> method under the covers.</para> /// <para>Set the <see cref="StreamWriteSizeInBytes"/> property before calling this method to specify the block size to write, in bytes, /// ranging from between 16 KB and 4 MB inclusive.</para> /// <para>To throw an exception if the blob exists instead of overwriting it, pass in an <see cref="AccessCondition"/> /// object generated using <see cref="AccessCondition.GenerateIfNotExistsCondition"/>.</para> /// </remarks> public virtual Task<CloudBlobStream> OpenWriteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) { this.attributes.AssertNoSnapshot(); operationContext = operationContext ?? new OperationContext(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); if ((accessCondition != null) && accessCondition.IsConditional) { return Task.Run(async () => { try { await this.FetchAttributesAsync(accessCondition, options, operationContext, cancellationToken); } catch (Exception) { if ((operationContext.LastResult != null) && (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) && string.IsNullOrEmpty(accessCondition.IfMatchETag)) { // If we got a 404 and the condition was not an If-Match, // we should continue with the operation. } else { throw; } } CloudBlobStream stream = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); return stream; }, cancellationToken); } else { CloudBlobStream stream = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); return Task.FromResult(stream); } }
public IAsyncOperation<ICloudBlobStream> OpenWriteAsync(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) #endif { this.attributes.AssertNoSnapshot(); bool createNew = size.HasValue; BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient, false); if (!createNew && modifiedOptions.StoreBlobContentMD5.Value) { throw new ArgumentException(SR.MD5NotPossible); } #if ASPNET_K return Task.Run(async () => #else return AsyncInfo.Run(async (token) => #endif { if (createNew) { #if ASPNET_K await this.CreateAsync(size.Value, accessCondition, options, operationContext, cancellationToken); #else await this.CreateAsync(size.Value, accessCondition, options, operationContext).AsTask(token); #endif } else { #if ASPNET_K await this.FetchAttributesAsync(accessCondition, options, operationContext, cancellationToken); #else await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); #endif size = this.Properties.Length; } if (accessCondition != null) { accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); } #if ASPNET_K CloudBlobStream stream = new BlobWriteStream(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); #else ICloudBlobStream stream = new BlobWriteStreamHelper(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); #endif return stream; #if ASPNET_K }, cancellationToken); #else });