第七步:
在 WebRole 项目的 Web.Config 文件中的
<system.web>节下设置<httpRuntime maxRequestLength="2097151" executionTimeout="3600" />为什么要要这样做?
2097151B=2MB,即 IIS 能够处理一次请求的最大数据。也就是说,在正常情况下,你是无法直接上传大于 2M 的文件的。
在 BlobContainer.CreateBlob() 方法中,已经封装了对大文件(大于 2M 的文件)的处理。处理方式即分块方式(Block,详见Azure Services Platform Step by Step-(9) Windows Azure Storage概览。
好了,到目前为止,我们已经学会:取得 Blob Storage 认证、建立 Container、得到 Container 的实体、在 Container 中存储 Blob、删除 Blob、设置与获取 Blob 的 metadata 属性。
private bool PutLargeBlobImpl(BlobProperties blobProperties, Stream stream, bool overwrite, string eTag)
{
bool retval = false;
// Since we got a large block, chunk it into smaller pieces called blocks
long blockSize = BlockSize;
long startPosition = stream.Position;
long length = stream.Length - startPosition;
int numBlocks = (int)Math.Ceiling((double)length / blockSize);
string[] blockIds = new string[numBlocks];
//We can retry only if the stream supports seeking. An alternative is to buffer the data in memory
//but we do not do this currently.
RetryPolicy R = (stream.CanSeek ? this.RetryPolicy : RetryPolicies.NoRetry);
//Upload each of the blocks, retrying any failed uploads
for (int i = 0; i < numBlocks; ++i)
{
string blockId = Convert.ToBase64String(System.BitConverter.GetBytes(i));
blockIds[i] = blockId;
R(() =>
{
// Rewind the stream to appropriate location in case this is a retry
if (stream.CanSeek)
stream.Position = startPosition + i * blockSize;
NameValueCollection nvc = new NameValueCollection();
nvc.Add(QueryParams.QueryParamComp, CompConstants.Block);
//The block naming should be more elaborate to give more meanings on GetBlockList
nvc.Add(QueryParams.QueryParamBlockId, blockId);
long blockLength = Math.Min(blockSize, length - stream.Position);
retval = UploadData(blobProperties, stream, blockLength, overwrite, eTag, nvc);
});
}
// Now commit the list
// First create the output
using (MemoryStream buffer = new MemoryStream())
{
// construct our own XML segment with correct blockId's
XmlTextWriter writer = new XmlTextWriter(buffer, Encoding.UTF8);
writer.WriteStartDocument();
writer.WriteStartElement(XmlElementNames.BlockList);
foreach (string id in blockIds)
{
writer.WriteElementString(XmlElementNames.Block, id);
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
buffer.Position = 0; //Rewind
NameValueCollection nvc = new NameValueCollection();
nvc.Add(QueryParams.QueryParamComp, CompConstants.BlockList);
retval = UploadData(blobProperties, buffer, buffer.Length, overwrite, eTag, nvc);
}
return retval;
}
{
bool retval = false;
// Since we got a large block, chunk it into smaller pieces called blocks
long blockSize = BlockSize;
long startPosition = stream.Position;
long length = stream.Length - startPosition;
int numBlocks = (int)Math.Ceiling((double)length / blockSize);
string[] blockIds = new string[numBlocks];
//We can retry only if the stream supports seeking. An alternative is to buffer the data in memory
//but we do not do this currently.
RetryPolicy R = (stream.CanSeek ? this.RetryPolicy : RetryPolicies.NoRetry);
//Upload each of the blocks, retrying any failed uploads
for (int i = 0; i < numBlocks; ++i)
{
string blockId = Convert.ToBase64String(System.BitConverter.GetBytes(i));
blockIds[i] = blockId;
R(() =>
{
// Rewind the stream to appropriate location in case this is a retry
if (stream.CanSeek)
stream.Position = startPosition + i * blockSize;
NameValueCollection nvc = new NameValueCollection();
nvc.Add(QueryParams.QueryParamComp, CompConstants.Block);
//The block naming should be more elaborate to give more meanings on GetBlockList
nvc.Add(QueryParams.QueryParamBlockId, blockId);
long blockLength = Math.Min(blockSize, length - stream.Position);
retval = UploadData(blobProperties, stream, blockLength, overwrite, eTag, nvc);
});
}
// Now commit the list
// First create the output
using (MemoryStream buffer = new MemoryStream())
{
// construct our own XML segment with correct blockId's
XmlTextWriter writer = new XmlTextWriter(buffer, Encoding.UTF8);
writer.WriteStartDocument();
writer.WriteStartElement(XmlElementNames.BlockList);
foreach (string id in blockIds)
{
writer.WriteElementString(XmlElementNames.Block, id);
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
buffer.Position = 0; //Rewind
NameValueCollection nvc = new NameValueCollection();
nvc.Add(QueryParams.QueryParamComp, CompConstants.BlockList);
retval = UploadData(blobProperties, buffer, buffer.Length, overwrite, eTag, nvc);
}
return retval;
}