关键词:
总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块),但这不是我们现在说的重点,我们要做的事是保证在网络中断后1G的文件已上传的那部分在下次网络连接时不必再重传。所以我们本地在上传的时候,要将大文件进行分片,比如分成1024*1024B,即将大文件分成1M的片进行上传,服务器在接收后,再将这些片合并成原始文件,这就是分片的基本原理。断点续传要求本地要记录每一片的上传的状态,我通过三个状态进行了标记(wait loading finish),当网络中断,再次连接后,从断点处进行上传。服务器通过文件名、总片数判断该文件是否已全部上传完成。
下面来说细节:
1、首先获取文件(音视频、图片)
分两种情况,一种是在相册库里直接获取,一种是调用相机。如果是通过UIImagePickerView来获取(细节不详述,网上一大堆),我们会发现当你选定一个视频的时候,会出现图1的压缩页面,最后我们的app获取的视频就是这个经过压缩后的视频(不是视频库里的原始视频,这里有个注意点,操作完该压缩视频后记得释放,系统不会帮你释放的,需要你手动来操作,下面会说到),然后通过UIImagePickerView的协议方法中的- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info获取视频的Info
fileInfo = {
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/2AAE9E44-0E6D-4499-9AC3-93D44D8342EA/tmp/trim.F36EC46C-4219-43C8-96A7-FA7141AB64D2.MOV";
UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=DEDA9406-3223-4F87-ABB2-98FB5F5EB9C4&ext=MOV";
}
UIImagePickerControllerMediaType是选取文件的类型,如KUTTypeImage,KUTTypeMovie。这里注意一下movie和video的区别,一个是有声音的视频文件,一个是没有声音的视频文件,当然还有Audio是只有声音没有视频。UIImagePickerControllerMediaURL是视频的URL(如果是相机拍摄的,那么这个就是原始拍摄得到的视频;如果是在相册库里选择的,那就是压缩之后生成的视频),注意这个URL不指向相册库,通过这个URL你可以操作这个视频如删除,拷贝等,可以获取压缩后的视频的大小。UIImagePickerControllerReferenceURL是一个指向相册的URL,官方的解释是an NSURL that references an asset in the AssetsLibrary framework,通过这个URL,你可以获取视频的所有信息,包括文件名,缩略图,时长等(通过ALAssetsLibrary里的assetsLibrary assetForURL:referenceURL resultBlock:)。
如果是相机拍摄的,注意两个保存方法:图片保存到相册assetsLibrary writeImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation([info valueForKey:UIImagePickerControllerOriginalImage],(CGFloat)1.0) metadata:nil completionBlock: failureBlock:
高保真压缩图片的方法NSData * UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality)
视频保存到相册:assetsLibrary writeVideoAtPathToSavedPhotosAlbum:MediaURL completionBlock:failureBlock:
到这里,我们就获取了所有需要的文件以及文件信息。下面要做的就是将文件分片。
2、将获取到的文件分片
首先,我将获取到的文件保存在这这样一个类中
@interface CNFile : NSObject
@property (nonatomic,copy) NSString* fileType;//image or movie
@property (nonatomic,copy) NSString* filePath;//文件在app中路径
@property (nonatomic,copy) NSString* fileName;//文件名
@property (nonatomic,assign) NSInteger fileSize;//文件大小
@property (nonatomic,assign) NSInteger trunks;//总片数
@property (nonatomic,copy) NSString* fileInfo;
@property (nonatomic,strong) UIImage* fileImage;//文件缩略图
@property (nonatomic,strong) NSMutableArray* fileArr;//标记每片的上传状态
@end
这样我们就可以对每一个CNFile对象进行操作了。
-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{
总片数的获取方法:
int offset = 1024*1024;(每一片的大小是1M)
NSInteger chunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) + 1));
NSLog(@"chunks = %ld",(long)chunks);
将文件分片,读取每一片的数据:
NSData* data;
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:file.filePath];
[readHandle seekToFileOffset:offset * chunk];
data = [readHandle readDataOfLength:offset];
}
这样我们就获取了每一片要上传的数据,然后询问服务器,该片是否已经存在
(方法-(void)ifHaveData:(NSData*)data WithChunk:(NSInteger)chunk file:(CNFile*)file)
,如果存在,令chunk+1,重复上面的方法读取下一片,直到服务器不存在该片,那么上传该片数据。在这个方法中注意设置该chunk的上传状态(wait loading finish),这将关系到本地判断该文件是否已全部上传完成。
下一步就是上传的过程:
-(void)uploadData:(NSData*) data WithChunk:(NSInteger) chunk file:(CNFile*)file;
在服务器返回该片上传成功后,我们要做的事有很多:
1)先将已经成功上传的本片的flag置finish
[file.fileArr replaceObjectAtIndex:chunk withObject:@“finish"];
2)查看是否所有片的flag都已经置finish,如果都已经finishi,说明该文件上传完成,那么删除该文件,上传下一个文件或者结束。
for (NSInteger j = 0; j<chunks; j++){
if (j == chunks || ((j == chunks - 1)&&([file.fileArr[j] isEqualToString:@"finish"])))
[me deleteFile:file.filePath];
[me readNextFile];
}
3)如果没有都finish,那么看本地下一chunk对用的flag是否是wait
NSLog(@"查看第%ld片的状态",chunk+1);
for(NSInteger i = chunk+1;i < chunks;i++)
{
NSString* flag = [file.fileArr objectAtIndex:i];
if ([flag isEqualToString:@"wait"]) {
[me readDataWithChunk:i fileName:fileName file:file];
break;
}
}
在第2、3步之间可以有一个 2.5)判断是否暂停上传
if(me.isPause == YES)
{
//将目前读到了第几个文件的第几片保存到本地
[self saveProgressWithChunk:chunk file:file];
return ;
}
这个操作实际上和上传过程中断网是一样的,为了断点续传,在断网或者暂停的时候,我们要将目前的进度保存起来,以便下次上传时略过前面已置finish的片。
然后还有一个问题,如果我们就这样线性的一片一片上传,实际上失去了分片上传的意义,应该结合多线程,使分片上传过程并发执行,同时上传多片,这样就提高了上传效率,并充分利用了网络带宽。
dispatch_async(dispatch_queue_t queue, ^{
[me readDataWithChunk: chunk];
})
最后注意一下,每上传完一个视频,去设置里看看你的app占用的存储空间有没有增大哦,如果你没有处理那个生成的压缩视频,你会发现你的app的空间占用量是很大的。
转自:http://blog.5ibc.net/p/73861.html
springboot实现分片上传断点续传大文件极速秒传-备忘(代码片段)
文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进行上传,这可不是一个好的办法,毕竟很少有人会忍受,当文件上传... 查看详情
大文件分片上传,断点续传,秒传实现
...一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中断,必须重新上传导致前功尽弃; 解决方案:1,修改服务端上传的限制配置;Nginx以... 查看详情
前端实现大文件上传分片上传断点续传
总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情
项目难点——断点续传分片上传(代码片段)
项目难点——【2】断点续传、分片上传1文件分片在网络请求中,如果我们有时是上传大文件,可能由于网络原因,导致上传断断续续,很难一次性上传成功,那么这个时候我们就需要将大文件分块,分成... 查看详情
jsp利用webuploader实现超大文件分片上传断点续传
需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制。第一步:前端修改由于项目使用的是BJUI前端框架,并... 查看详情
一文搞懂分片上传和断点续传(代码片段)
...夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这两种上传的方法的用法还是有点... 查看详情
一文搞懂分片上传和断点续传(代码片段)
...夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这两种上传的方法的用法还是有点... 查看详情
java如何实现大文件分片上传,断点续传和秒传
Java如何实现大文件分片上传,断点续传和秒传引言概念秒传1、什么是秒传2、实现秒传常见做法分片上传1、什么是分片上传2、分片上传的场景断点续传1、什么是断点续传2、应用场景3、实现断点续传的核心逻辑实现思路前置知识... 查看详情
超大文件上传和断点续传的源代码
总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情
10g大文件上传最全方案:秒传断点续传分片上传,包教会!
上一篇:麻了!Fastjson再曝反序列化漏洞。。前言文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进... 查看详情
teracloud传不了大文件
teracloud传不了超过5G大文件。传大文件用以下方法解决如果我们需要使用工具上传单个或者多个大文件,而不是使用API、SDK编写代码上传时,可以使用ossutil。1、可以使用ossutil命令行工具的cp命令上传大文件2、可通过–bigfile-thres... 查看详情
如何使用断点续传上传大文件
概念大文件上传的需求介绍不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂。文件上传简单,文件变大就复杂上传大文件时,以下几个变量会影响我们的用户体验服务器处理数据的能力请求超时... 查看详情
前端+后端实现分片上传(断点续传/极速秒传)(代码片段)
...下,后面有时间再去实现可参考链接:vue上传大文件/视频前后端(java)代码前端+后端实现分片上传(断点续传/极速秒传)前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当... 查看详情
springboot分片上传断点续传大文件极速秒传功能,这篇都帮你搞定!(典藏版)...(代码片段)
文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进行上传,这可不是一个好的办法,毕竟很少有人会... 查看详情
vue超大文件上传解决方案:分片断点上传
众所皆知,web上传大文件,一直是一个痛。上传文件大小限制,页面响应时间超时.这些都是web开发所必须直面的。本文给出的解决方案是:前端实现数据流分片长传,后面接收完毕后合并文件的思路。实现文件夹上传,要求:... 查看详情
csharp文件分片上传,断点续传
需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制。 第一步:前端修改由于项目使用的是BJUI前端框架,... 查看详情
网页大文件分片上传处理
总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情
如何用xmlhttprequest实现大文件上传和断点续传
...象,能够实现断店续传。我说一下我的思路吧:首先获取文件的MD5(spark-md5.js),然后利用文件对象的slice方法进行切割文件,分段上传到后台,后台组装文件然后校验MD5值;我也刚好在做,觉得可行本回答被提问者采纳 查看详情