Multi-threaded breakpoints in iOS development download large files

Source: Internet
Author: User

The main idea is to create a blank file with the size of the target file, and then segment the data into this blank file.

You can get the exact size of the file in the server by sending a head request, and then split the length into chunks of data that are set by the GET request.

Request header information, you can determine the starting length and end length of the downloaded file in a single thread.

For example, the target file size 900M, when downloading, open three threads to download, size = 300. Then the first thread should be 0~~299m's task.

The second thread is the 300~~599m task, and the third is the last size of the 600m~~, and when it cannot be divisible, each size+1 to avoid causing errors.

When writing to the file (which is the side of the download side write), the file handle (Nsfilehandle) is moved to the end of the currently downloaded file and then written.

When the download is complete, you need to close the current file handle.

@interface zyfiledownload:nsobject{    BOOL _downloading;} Are you downloading @property (nonatomic, ReadOnly, getter=isdownloading) BOOL downloading;//target path, which is the storage path @property (nonatomic, copy) nsstring *goalpath;//download Resource url@property (nonatomic, copy) nsstring *urlstr;//download Progress @property (nonatomic, copy) void ( ^progresshandler) (double progress);//Start download-(void) start;//end download-(void) pause; @end #import "ZYFileDownLoad.h" @ Implementation Zyfiledownload@end

 

#import "ZYFileDownLoad.h" @interface zymultifiledownload:zyfiledownload@end#import "ZYMultiFileDownLoad.h" #import "ZYSingleDownLoad.h" #define Zymaxdownloadcount 3@interface zymultifiledownload () @property (nonatomic, Strong) Nsmutablearray *singledownloads; @property (nonatomic, assign) long long totallength; @end @implementation zymultifiledownload-(void) getfilesize{//Send a HEAD request to get specific information about the data in the server response header content-length Nsmutableurlrequest *request =    [[Nsmutableurlrequest alloc] Initwithurl:[nsurl URLWithString:self.urlStr]]; Request.    HttpMethod = @ "HEAD";    Nsurlresponse *response = nil;    You can also send asynchronous requests for information [nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:nil]; Get file size self.totallength = response.expectedcontentlength;}                -(Nsmutablearray *) singledownloads{if (_singledownloads = = nil) {_singledownloads = [Nsmutablearray array];                [Self getfilesize];                A long long size = 0;        Number of downloads per pathif (self.totallength% Zymaxdownloadcount = = 0) {size = Self.totallength/zymaxdownloadcount;        } else{size = Self.totallength/zymaxdownloadcount + 1; }//Create n downloader for (int i = 0; i < Zymaxdownloadcount; i++) {Zysingledownload *singledow            nload = [[Zysingledownload alloc] init];            Singledownload.urlstr = Self.urlstr;            Singledownload.goalpath = Self.goalpath;            Singledownload.beginlength = i * size;            Singledownload.endlength = (i + 1) * SIZE-1;            Singledownload.progresshandler = ^ (double progress) {//The Progress action can be set here};                        [_singledownloads Addobject:singledownload]; Create a temporary file with size such as server file [[Nsfilemanager Defaultmanager] CreateFileAtPath:self.goalPath contents:nil attributes:ni                        L]; Let the length of the Self.goalpath file be self.totallengt nsfilehandle *writehandle = [Nsfilehandle filesHandleForWritingAtPath:self.goalPath];        [Writehandle TruncateFileAtOffset:self.totalLength]; }} return _singledownloads;}    -(void) start{[self.singledownloads makeobjectsperformselector: @selector (start)]; _downloading = YES;}    -(void) pause{[self.singledownloads makeobjectsperformselector: @selector (pause)]; _downloading = NO;} @end

 

@interface Zysingledownload:zyfiledownload@property (nonatomic, assign) a long long beginlength; @property (Nonatomic, Assign) long long endlength, @end #import "ZYSingleDownLoad.h" @interface zysingledownload () < Nsurlconnectiondatadelegate> @property (nonatomic, assign) long long currentlength; @property (nonatomic, Strong) Nsurlconnection *connection; @property (nonatomic, strong) Nsfilehandle *writehandle; @end @implementation zysingledownload-(Nsfilehandle *) writehandle{if (!_writehandle) {_writehandle = [Nsfilehandle fileHandleForWr    ItingAtPath:self.goalPath]; } return _writehandle;}        -(void) start{nsurl *url = [Nsurl URLWithString:self.urlStr];    Nsmutableurlrequest *request = [[Nsmutableurlrequest alloc] initwithurl:url]; Set the request body, starting from which data segment to download nsstring *values = [NSString stringwithformat:@ "Bytes=%lld-%lld", Self.beginlength +    Self.currentlength,self.endlength];        [Request Setvalue:values forhttpheaderfield:@ "Range"]; Self.connection = [NsurlconneCtion Connectionwithrequest:request delegate:self]; _downloading = YES;}        -(void) pause{[self.connection Cancel]; Self.connection = nil;} #pragma mark--------nsurlconnectiondatadelegate-(void) connection: (Nsurlconnection *) connection Didreceiveresponse :(Nsurlresponse *) response{}-(void) connection: (Nsurlconnection *) connection didreceivedata: (NSData *) data{//move to Text    The tail of the piece [Self.writehandle seekToFileOffset:self.beginLength + self.currentlength];        Writes data starting at the current moving position (end of file) [Self.writehandle Writedata:data];        Cumulative length Self.currentlength + = Data.length;    Print download Progress Double progress = (double) self.currentlength/(Self.endlength-self.beginlength);    if (Self.progresshandler) {Self.progresshandler (progress);        }}-(void) connectiondidfinishloading: (nsurlconnection *) connection{//emptying attribute value self.currentlength = 0;    Close connection [Self.writehandle CloseFile]; Self.writehandle = nil;} -(void) connection: (Nsurlconnection *) connection Didfailwitherror: (Nserror *) error{} @end 

Multi-threaded breakpoints in iOS development download large files

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.