iOS大文件的分片上传和断点上传

iOS大文件的分片上传和断点上传,第1张

由于最近比较忙,所以一直没有写博客,现在分享一些大文件上传的问题!断点续传和分片上传。因为文件过大(比如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里的assetsLibraryassetForURL:referenceURLresultBlock:)。

如果是相机拍摄的,注意两个保存方法:图片保存到相册assetsLibrarywriteImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation([infovalueForKey:UIImagePickerControllerOriginalImage],(CGFloat)1.0)metadata:nilcompletionBlock: failureBlock:

高保真压缩图片的方法NSData * UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality)

视频保存到相册:assetsLibrarywriteVideoAtPathToSavedPhotosAlbum: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)NSIntegerfileSize//文件大小

@property (nonatomic,assign)NSIntegertrunks//总片数

@property(nonatomic,copy)NSString* fileInfo

@property(nonatomic,strong)UIImage* fileImage//文件缩略图

@property(nonatomic,strong) NSMutableArray* fileArr//标记每片的上传状态

@end

这样我们就可以对每一个CNFile对象进行 *** 作了。

-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{

总片数的获取方法:

intoffset =1024*1024(每一片的大小是1M)

NSIntegerchunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) +1))

NSLog(@"chunks = %ld",(long)chunks)

将文件分片,读取每一片的数据:

NSData* data

NSFileHandle*readHandle = [NSFileHandlefileHandleForReadingAtPath:file.filePath]

[readHandleseekToFileOffset:offset * chunk]

data = [readHandlereadDataOfLength: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.fileArrreplaceObjectAtIndex:chunk withObject:@“finish"]

2)查看是否所有片的flag都已经置finish,如果都已经finishi,说明该文件上传完成,那么删除该文件,上传下一个文件或者结束。

for(NSIntegerj =0j

if(j == chunks || ((j == chunks -1)&&([file.fileArr[j]isEqualToString:@"finish"])))

[medeleteFile:file.filePath]

[mereadNextFile]

}

3)如果没有都finish,那么看本地下一chunk对用的flag是否是wait

NSLog(@"查看第%ld片的状态",chunk+1)

for(NSIntegeri = chunk+1i <chunksi++)

{

NSString* flag = [file.fileArrobjectAtIndex:i]

if([flagisEqualToString:@"wait"]) {

[mereadDataWithChunk:ifileName:fileNamefile:file]

break

}

}

在第2、3步之间可以有一个 2.5)判断是否暂停上传

if(me.isPause ==YES)

{

//将目前读到了第几个文件的第几片保存到本地

[selfsaveProgressWithChunk:chunk file:file]

return

}

这个 *** 作实际上和上传过程中断网是一样的,为了断点续传,在断网或者暂停的时候,我们要将目前的进度保存起来,以便下次上传时略过前面已置finish的片。

然后还有一个问题,如果我们就这样线性的一片一片上传,实际上失去了分片上传的意义,应该结合多线程,使分片上传过程并发执行,同时上传多片,这样就提高了上传效率,并充分利用了网络带宽。

dispatch_async(dispatch_queue_t queue, ^{

[mereadDataWithChunk: chunk]

})

最后注意一下,每上传完一个视频,去设置里看看你的app占用的存储空间有没有增大哦,如果你没有处理那个生成的压缩视频,你会发现你的app的空间占用量是很大的。

站在大牛的肩膀上开发。

方式不同。

1、断点上传,是通时间规定的间隔进行文件传输的一种。

2、而断点续传断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载。

问题一:网络断点续传是什么意思 有时用户上传下载文件需要历时数小时,万一线路中断,不具备断点续传的FTP服务器或下载软件就只能从头重传,比较好的FTP服务器或下载软件具有FTP断点续传能力,允许用户从上传下载断线的地方继续传送,这样大大减少了用户的烦恼。

IE浏览器默认下载方式不支持断点续传。

常见的支持断点续传的上传、下载软件:QQ旋风、迅雷、快车(迷你快车)、web迅雷、影音传送带、快车、Bitet、电驴eMule、哇嘎Vagaa、RF[RaySourse/RayFile]、酷6、土豆、优酷、百度视频、新浪视频、腾讯视频、百度云等都支持断点续传,在陶诺网络科技,网站里面也有相关的工具下载,可以百度一下进去下载。

在 *nix(Linux/Unix)系统下,常用支持断点续传的FTP客户端软件是lftp。

特点

断点续传支持从文件上次中断的地方开始传送数据,而并非是从文件开头传送。

断点续传下载软件具有以下特点:

1、断点续传功能,既可节约时间又可以节约金钱。

2、定时下载功能,可以为将要下载的软件制定一任务列表,让下载软件在规定的时间自动拨号上网并下载软件,下载完毕后再自动挂起Modem,断开与internet的连接,甚至自动关闭计算机。

3、多文件同时下载。

4、支持拖放式 *** 作,可将下载文件的URL超链接用鼠标拖放到下载软件的窗口上,即可激活下载软件,同时开始文件的下载。

5、自动捕捉剪贴板上的URL并激活下载软件,可以捕捉到剪贴板中的URL,甚至浏览器中单击下载文件超链接,即可激活程序实现文件的下载。

6、致命错误发生时的关闭机制。

7、预防病毒侵害的安全机制,文件下载完毕,即可自动将其发送到指定的病毒的检测软件进行病毒扫描。

断点续传下载软件包括Thunder、NetAnts、FlashGet、Net Vampire、Download Manager、GetRight、Go!Zilla、WinDownload等。

问题二:什么是断点续传,有什么优点 断点续传支持从文件上次中断的地方开始传送数据,而并非是从文件开头传送。

问题三:什么是断点续传,有什么优点 也就是可以暂停下载 再重新开始下载

好处是 万一你下载的时候突然断网了 如果有断电续传的话 可以在连上网后 继续下载~

普通下载可不行~~

问题四:断点续传是什么意思 就是信号中断后(掉线或关机等),下次能够从上次的地方接着传送(一般指下载或上传),不支持断点续传就意味着下次下载或上传必须从零开始.$

一般常用的网际快车就支持断点续传啊,断点大小是可以设置的,比如设为200KB,意思就是每下载200KB的文件,就自动保存一次。举个例子你就明白了:=l

比如你将下载的某软件大小为250KB。断点大小设为200KB的话,如果刚下载至240KB时突然断电,还差10KB没有下载,这时下次下载时,该软件就有200KB的文件已保存在你的电脑里,只需接着下载下差的50KB就可以了。

问题五:什么叫断点续传功能?我下了一半的文件中途断网了,之后能继续之前的下载吗 你说对了

问题六:什么是断点续传? 就是信号中断后(掉线或关机等),下次能够从上次的地方接着传送(一般指下载或上传),不支持断点续传就意味着下次下载或上传必须从零开始.$

一般常用的网际快车就支持断点续传啊,断点大小是可以设置的,比如设为200KB,意思就是每下载200KB的文件,就自动保存一次。举个例子你就明白了:=l

迅雷上次没传完,下次打开,就可以直接传了

问题七:如何实现断点续传 其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下: 假设服务器域名为w sjtu.edu,文件名为down.zip。 GET /down.zip HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- excel, application/msword, application/vnd.ms-powerpoint, */* Accept-Language: zh- Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (patibleMSIE 5.01Windows NT 5.0) Connection: Keep-Alive 服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下: 200 Content-Length=106786028 Accept-Ranges=bytes Date=Mon, 30 Apr 2001 12:56:11 GMT ETag=W/02ca57e173c11:95b Content-Type=application/octet-stream Server=Microsoft-IIS/5.0 Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT 所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给 Web服务器的时候要多加一条信息--从哪里开始。 下面是用自己编的一个浏览器来传递请求信息给Web服务器,要求从2000070字节开始。 GET /down.zip HTTP/1.0 User-Agent: NetFox RANGE: bytes=2000070- Accept: text/html, image/gif, image/jpeg, *q=.2, */*q=.2 仔细看一下就会发现多了一行RANGE: bytes=2000070- 这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。 服务器收到这个请求以后,返回的信息如下: 206 Content-Length=106786028 Content-Range=bytes 2000070-106786027/106786028 Date=Mon, 30 Apr 2001 12:55:20 GMT ETag=W/02ca57e173c11:95b Content-Type=application/octet-stream Server=Microsoft-IIS/5.0 Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT 和前面服务器返回的信息比......>>

问题八:什么是不支持断点续传 通过等待或者选择试用的方式开始下载

一般都是右键另存为的方式下载

但是如果用影音快车的话,就可以断点多线下载了

其实迅雷也可以的


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11644428.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存