Windows Azure: 使用Blob的PutBlock实现大文件断点续传
2013-01-18 17:19
218 查看
我们在使用Blob服务的时候,免不了要上传大文件,采用一般方式(UploadFromStream)上传数据,如果由于网络或是其他因素导致传输中断,则整个传输前功尽弃。针对这种情况,我们可以使用Blob的PutBlock机制将大文件分块(即分成若干个block)传输,并且实现断点续传。在这里我们通过一个例子来看看如何实现分块传输以及断点续传。
首先我们来看一下两个方法的定义:
PutBlock,上传单个Block数据。
blockId, 使用Base64编码格式,代表了唯一的block;
blockData,block包含的数据流;
contentMD5,用来验证block完整性的哈希值,可以为Null或是空串。
PutBlockList:根据blockId集合提交所有的block,并创建或更新blob文件。只有提交以后,通过PutBlock上传的块数据才能成为Blob文件的一部分。
blockList,blockId集合;
options,给请求定义的额外的配置。
对于分块传输的实现步骤,描述如下:
首先确定每一个block的大小,Blob服务规定Block最大不能超过4MB;
然后通过FileStream的Read方法依次按量读取块数据,并依次调用PutBlock将块数据上传,每次上传时需要一个对应的blockId,上传成功以后将对应的blockId存储;
所有Block上传完成以后,调用PutBlockList提交将才上传的所有block,组成blob文件。(注意,对于未提交的Block数据,一个星期之内将被自动回收。)
分块上传搞定以后,到底如何实现断点续传呢?
我们来看,假如100M的数据,每个block 1M,当我们上传了50个block的时候突然网断了,在网络断开的那一刻,我们能确定,到底成功上传了多少份Block,以及成功上传的block对应的block Id。对于同一文件,大小是不变的,所以我们可以根据传输了多少份block来确定续传时该从文件的那个位置开始继续读取block数据,并继续传输剩余的block。并且最后调用PutBlockList来提交网断前后上传的所有Block Id,最终完成传输。
好了,废话不多说,上代码,朋友们一看就明白。
这里使用了windows form application来演示断点续传,如图所示,点击"End”可模拟传输中断,再点击"Start”可模拟续传。
例子中使用了BackGroundWorker组件实现后台操作上传数据,前台进度条刷新。传输成功的block Id存储在内存中(List<string>),实际情况可能大家要考虑使用其他更为安全的存储方式以保证能续传。
断点续传分块数据主要代码:
点击 这里 下载源码。
首先我们来看一下两个方法的定义:
PutBlock,上传单个Block数据。
public void PutBlock (
string blockId,
Stream blockData,
string contentMD5
)
blockId, 使用Base64编码格式,代表了唯一的block;
blockData,block包含的数据流;
contentMD5,用来验证block完整性的哈希值,可以为Null或是空串。
PutBlockList:根据blockId集合提交所有的block,并创建或更新blob文件。只有提交以后,通过PutBlock上传的块数据才能成为Blob文件的一部分。
public void PutBlockList (
IEnumerable<string> blockList,
BlobRequestOptions options
)
blockList,blockId集合;
options,给请求定义的额外的配置。
对于分块传输的实现步骤,描述如下:
首先确定每一个block的大小,Blob服务规定Block最大不能超过4MB;
然后通过FileStream的Read方法依次按量读取块数据,并依次调用PutBlock将块数据上传,每次上传时需要一个对应的blockId,上传成功以后将对应的blockId存储;
所有Block上传完成以后,调用PutBlockList提交将才上传的所有block,组成blob文件。(注意,对于未提交的Block数据,一个星期之内将被自动回收。)
分块上传搞定以后,到底如何实现断点续传呢?
我们来看,假如100M的数据,每个block 1M,当我们上传了50个block的时候突然网断了,在网络断开的那一刻,我们能确定,到底成功上传了多少份Block,以及成功上传的block对应的block Id。对于同一文件,大小是不变的,所以我们可以根据传输了多少份block来确定续传时该从文件的那个位置开始继续读取block数据,并继续传输剩余的block。并且最后调用PutBlockList来提交网断前后上传的所有Block Id,最终完成传输。
好了,废话不多说,上代码,朋友们一看就明白。
这里使用了windows form application来演示断点续传,如图所示,点击"End”可模拟传输中断,再点击"Start”可模拟续传。
例子中使用了BackGroundWorker组件实现后台操作上传数据,前台进度条刷新。传输成功的block Id存储在内存中(List<string>),实际情况可能大家要考虑使用其他更为安全的存储方式以保证能续传。
断点续传分块数据主要代码:
private void UploadBigFile(BackgroundWorker worker, DoWorkEventArgs e) { //bufferSize 40KB byte[] bufferBytes = new byte[bufferSize]; string fileName = Path.GetFileName(filePath); CloudBlockBlob blob = GetBlobkBlob(fileName); using (FileStream fileStream = File.OpenRead(filePath)) { //Get the total count of block blockCount = (int)(fileStream.Length / bufferSize) + 1; Int64 currentBlockSize = 0; for (int i = blockIds.Count; i < blockCount; i++) { if (worker.WorkerSupportsCancellation && worker.CancellationPending) { return; } currentBlockSize = bufferSize; if (i == blockCount - 1) { currentBlockSize = fileStream.Length - bufferSize * i; bufferBytes = new byte[currentBlockSize]; } if (currentBlockSize == 0) break; //Get the block data fileStream.Read(bufferBytes, 0, Convert.ToInt32(currentBlockSize)); using (MemoryStream memoryStream = new MemoryStream(bufferBytes)) { try { //Get Base64-encoded block Id string blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())); //Upload the block blob.PutBlock(blockId, memoryStream, null); //Cache the block Id blockIds.Add(blockId); worker.ReportProgress(i + 1); } catch (Exception) { } } } } //Commit all the blocks blob.PutBlockList(blockIds); isCanceled = false; } private CloudBlockBlob GetBlobkBlob(string fileName) { var storageAccount = CloudStorageAccount.Parse(storageConnectionString); CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobStorage.GetContainerReference("mycontainer"); container.CreateIfNotExists(); return container.GetBlockBlobReference(fileName); }
点击 这里 下载源码。
相关文章推荐
- Android 使用socket通信来实现文件断点续传上传
- 文件批量上传的工具,要实现暂停继续、断点续传等功能(使用QtNetwork和QHttpMultiPart,和定时器检查超时)
- 【SFTP】使用Jsch实现Sftp文件下载-支持断点续传和进程监控
- [New Portal]Windows Azure Storage (14) 使用Azure Blob的PutBlock方法,实现文件的分块、离线上传
- 使用HASH算法实现文件的断点续传
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- (二)使用libcurl实现获取目标文件大小, 下载进度显示, 断点续传等功能
- 使用libcurl实现获取目标文件大小, 下载进度显示, 断点续传等功能
- 使用CFtpconnection类实现文件的断点续传的问题
- iOS开发-使用NSURLSession实现文件断点下载,文件离线续传以及图片上传
- 使用NSURLConnection实现大文件断点下载
- C#实现上传文件分割,断点续传上传文件
- Electron中实现大文件上传和断点续传功能
- 以多线程、断点续传方式下载文件的实现
- 嵌入式 FTP断点续传原理以及实现指定下载文件起始地址
- 使用Nginx实现文件上传,或文件断点上传
- ios断点续传:通过NSURLSession实现文件下载功能
- 用HttpListener实现文件断点续传
- 使用.NET实现断点续传