First, File download
There are two ways to get the resource file size
1.
HTTP Head method Nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url cachepolicy:0 TimeoutInterval: Ktimeout];request. HttpMethod = @ "HEAD"; [Nsurlconnection sendasynchronousrequest:request queue:self.myQueue completionhandler:^ (Nsurlresponse *response, NSData *data, Nserror *connectionerror) { NSLog (@ "%@", response); NSLog (@ "---------------"); NSLog (@ "%@", data);}]; Running the test code reveals that the head method simply returns the resource information without returning the data body scenario: Get the resource mimetype get the resource file size for endpoint continuation or multi-threaded download
2
method to get network resource size using block code-(void) Filesizewithurl: (nsurl *) URL completion: (void (^) (long long contentlength)) completion{ Nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url cachepolicy:0 timeoutInterval:kTimeout]; Request. HttpMethod = @ "HEAD"; Nsurlresponse *response = nil; [Nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:NULL]; Completion (response.expectedcontentlength);}
determine the pseudo-code implementation of each download packet
-(void) Downloadfilewithurl: (Nsurl *) url{ [self filesizewithurl:url completion:^ (long long contentlength) { NSLog (@ "Total file size:%lld", contentlength); Download files according to size while (ContentLength > Kdownloadbytes) { NSLog (@ "Each download length:%lld", (Long Long) kdownloadbytes); ContentLength-= kdownloadbytes; } NSLog (@ "Last downloaded bytes:%lld", contentlength); }];}
An example of an HTTP range
You can specify the size of each packet to be downloaded from the network by setting the range
Range Example
bytes=0-499 The first 500 bytes from 0 to 499
bytes=500-999 The second 500 bytes from 500 to 999
bytes=500- All bytes since 500 bytes
bytes=-500 Last 500 bytes
bytes=500-599,800-899 Specify several ranges at the same time
Range Summary
- Used to separate
The preceding number indicates the starting byte number
The following array represents the number of cutoff bytes and does not represent the end
, For grouping, you can specify more than one range at a time, but rarely
Segmented range code implementation long Long frombytes = 0;long long tobytes = 0;while (ContentLength > Kdownloadbytes) { tobytes = Frombyt Es + kDownloadBytes-1; NSString *range = [NSString stringwithformat:@ "Bytes=%lld-%lld", Frombytes, tobytes]; NSLog (@ "range%@", range); Frombytes + = kdownloadbytes; ContentLength-= kdownloadbytes;} Frombytes = frombytes + contentLength-1; NSString *range = [NSString stringwithformat:@ "Bytes=%lld-%lld", Frombytes, tobytes]; NSLog (@ "range%@", range);
Segment Download file nsmutableurlrequest *request = [Nsmutableurlrequest requestwithurl:url cachepolicy: Nsurlrequestreloadignoringcachedata Timeoutinterval:ktimeout]; NSString *range = [NSString stringwithformat:@ "Bytes=%lld-%lld", from, end]; [Request Setvalue:range forhttpheaderfield:@ "range"]; Nsurlresponse *response = nil; NSData *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:NULL]; NSLog (@ "%@-%@-%ld", Range, response, (unsigned long) data.length); Tip: If get contains a range request header, The response is returned as a status code of 206 (partialcontent) instead of a (OK)
Write data to File//Open cache file Nsfilehandle *FP = [Nsfilehandle filehandleforwritingatpath:self.cachepath];//If file does not exist, write data directly if (!FP) { [data WriteToFile:self.cachePath atomically:yes];} else { //move to end of file [FP seektoendoffile]; Append the data file to the end of the file [FP writedata:data]; Close file handle [FP closefile];}
Check the file size//Determine if the file exists if ([[[Nsfilemanager Defaultmanager] FileExistsAtPath:self.cachePath]) { nsdictionary *dict = [[ Nsfilemanager Defaultmanager] AttributesOfItemAtPath:self.cachePath error:null]; return [dict[nsfilesize] longlongvalue];} else { return 0;} Tip: Because the data is appended, in order to avoid repeatedly downloading files from the network, before downloading, determine whether the file already exists in the cache path if there is a check file size if the file size matches the size of the network resource, it is no longer downloaded
The entire code is as follows
mjviewcontroller.m// 01. File Download//// Created by Apple on 14-4-29.// Copyright (c) 2014 itcast. All rights reserved.//#import "MJViewController.h" #import "FileDownload.h" @interface Mjviewcontroller () @property ( Nonatomic, strong) FileDownload *download; @property (weak, nonatomic) Iboutlet Uiimageview *imageview;@ End@implementation mjviewcontroller-(void) viewdidload{ [Super Viewdidload]; Self.download = [[FileDownload alloc] init]; [Self.download downloadfilewithurl:[nsurl urlwithstring:@ "Http://localhost/itcast/images/head4.png"] completion : ^ (UIImage *image) { self.imageView.image = image; }];} @end
filedownload.m//01. File Download////Created by Apple on 14-4-29.//Copyright (c) 2014 itcast. All rights reserved.//#import "FileDownload.h" #import "nsstring+password.h" #define ktimeout 2.0f//number of bytes per download # define Kbytespertimes 20250@interface filedownload () @property (nonatomic, strong) NSString *cachefile; @property (Nonatomic, Strong) UIImage *cacheimage, @end @implementation filedownload/** in order to ensure that the development of the simple, all methods do not use multi-threading, all the attention is maintained on the file download In the development if you encounter a comparison of computational problems, it is recommended that: 1> test data is not too large 2> test data changes, you can use written calculation to calculate the exact value 3> write code control Test *///-(NSString *) cachefile//{//if ( !_cachefile) {//NSString *cachedir = Nssearchpathfordirectoriesindomains (Nscachesdirectory, NSUserDomainMask, YES) [0];//_cachefile = [Cachedir stringbyappendingpathcomponent:@ "123.png"];//}//return _cachefile;//}-(UIIma GE *) cacheimage{if (!_cacheimage) {_cacheimage = [UIImage imageWithContentsOfFile:self.cacheFile]; } return _cacheimage;} -(void) Setcachefile: (NSString *) urlstr{nsstring *cAchedir = Nssearchpathfordirectoriesindomains (Nscachesdirectory, Nsuserdomainmask, YES) [0]; URLSTR = [Urlstr MD5]; _cachefile = [Cachedir stringbyappendingpathcomponent:urlstr];} -(void) Downloadfilewithurl: (nsurl *) URL completion: (void (^) (UIImage *image)) completion{//GCD Serial Queue Async method Dispatch_ queue_t q = dispatch_queue_create ("Cn.itcast.download", dispatch_queue_serial); Dispatch_async (q, ^{NSLog (@ "%@", [Nsthread CurrentThread]); The result of MD5 encryption of the URL is the file name self.cachefile = [url absolutestring]; 1. To download files from the network, you need to know the size of this file long fileSize = [self filesizewithurl:url]; Calculate local cache file size long long cachefilesize = [self localfilesize]; if (cachefilesize = = fileSize) {Dispatch_async (Dispatch_get_main_queue (), ^{completion (self.ca Cheimage); }); NSLog (@ "file already exists"); Return }//2. Determine the size of each packet long Fromb= 0; Long long ToB = 0; Computes the starting and ending bytes while (fileSize > Kbytespertimes) {//20480 + 20480//ToB = fr OmB + kBytesPerTimes-1; 3. segmented download file [self downloaddatawithurl:url fromb:fromb Tob:tob]; FileSize-= Kbytespertimes; Fromb + = Kbytespertimes; } [Self Downloaddatawithurl:url fromb:fromb tob:fromb + fileSize-1]; Dispatch_async (Dispatch_get_main_queue (), ^{completion (self.cacheimage); }); });} #pragma mark downloads A packet of the specified byte range/** nsurlrequestuseprotocolcachepolicy = 0,//default cache policy, memory cache Nsurlrequestreloadignoringloc Alcachedata = 1,//ignore local memory cache Nsurlrequestreloadignoringcachedata */-(void) Downloaddatawithurl: (nsurl *) URL Fromb: ( Long long) Fromb ToB: (Long Long) tob{NSLog (@ "packet:%@", [Nsthread CurrentThread]); Nsmutableurlrequest *request = [Nsmutableurlrequest requestwithurl:url cachepolicy:nsurlrequestrEloadignoringcachedata Timeoutinterval:ktimeout]; Specify the byte range to get in the request nsstring *range = [NSString stringwithformat:@ "Bytes=%lld-%lld", Fromb, ToB]; [Request Setvalue:range forhttpheaderfield:@ "range"]; NSLog (@ "%@", range); Nsurlresponse *response = nil; NSData *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:NULL]; Write file, overwrite file will not append//[Data writetofile:@ "/users/aplle/desktop/1.png" atomically:yes]; [Self appenddata:data]; NSLog (@ "%@", Response);} #pragma mark-read local cache file size-(long Long) localfilesize{//Read local file information nsdictionary *dict = [[Nsfilemanager Defaultmanager ] AttributesOfItemAtPath:self.cacheFile Error:null]; NSLog (@ "%lld", [Dict[nsfilesize] longlongvalue]); return [dict[nsfilesize] longlongvalue];} #pragma mark-Append data to File-(void) AppendData: (NSData *) data{//Determine if file exists nsfilehandle *FP = [Nsfilehandle filehandleforw RitingAtPath:self.cacheFile]; If the file does not exist, create the file if (!FP) { [Data writeToFile:self.cacheFile Atomically:yes]; } else {//If file already exists append file//1> move to end of file [FP Seektoendoffile]; 2> additional data [FP Writedata:data]; 3> write file [fp CloseFile]; }} #pragma mark-Get Network File Size-(Long Long) Filesizewithurl: (Nsurl *) url{//default is get nsmutableurlrequest *request = [Nsmuta Bleurlrequest Requestwithurl:url cachepolicy:0 Timeoutinterval:ktimeout]; Head, just return the information of the file resource, do not return the specific data//If you want to get the resources of the mimetype, also must use head, otherwise, the data will be repeated download two times request. HttpMethod = @ "HEAD"; Use the sync method to get the file size nsurlresponse *response = nil; [Nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:NULL]; Expectedcontentlength file size on the network NSLog (@ "%lld", response.expectedcontentlength); return response.expectedcontentlength;} @end
second, file upload
The code is as follows
mjviewcontroller.m// 02.Post upload//// Created by Apple on 14-4-29.// Copyright (c) 2014 itcast. All rights reserved.//#import "MJViewController.h" #import "UploadFile.h" @interface Mjviewcontroller () @ End@implementation mjviewcontroller-(void) viewdidload{ [Super Viewdidload]; UploadFile *upload = [[UploadFile alloc] init]; NSString *urlstring = @ "http://localhost/upload.php"; NSString *path = [[NSBundle mainbundle] pathforresource:@ "Avatar 1.png" oftype:nil]; NSData *data = [NSData Datawithcontentsoffile:path]; [Upload Uploadfilewithurl:[nsurl urlwithstring:urlstring] data:data];} @end
uploadfile.m//02.Post upload////Created by Apple on 14-4-29.//Copyright (c) 2014 itcast. All rights reserved.//#import "UploadFile.h" @implementation uploadfile//splicing string static nsstring *boundarystr = @ "--"; Delimited string static nsstring *randomidstr; This upload marked string static NSString *uploadid; Upload (PHP) script, receive file field-(instancetype) init{self = [super init]; if (self) {randomidstr = @ "Itcast"; Uploadid = @ "UploadFile"; } return self;} #pragma mark-Private Method-(NSString *) Topstringwithmimetype: (NSString *) MimeType uploadfile: (NSString *) uploadfile{NSMUTABL estring *STRM = [nsmutablestring string]; [StrM appendformat:@ "%@%@\n", Boundarystr, Randomidstr]; [StrM appendformat:@ "content-disposition:form-data; name=\"%@\ "; filename=\"%@\ "\ n", Uploadid, UploadFile]; [StrM appendformat:@ "Content-type:%@\n\n", MimeType]; NSLog (@ "%@", StrM); return [StrM copy];} -(NSString *) bottomstring{nsmutablestring *STRM = [NsmutablestrinG String]; [StrM appendformat:@ "%@%@\n", Boundarystr, Randomidstr]; [StrM appendstring:@ "content-disposition:form-data; name=\" submit\ "\ n"]; [StrM appendstring:@ "submit\n"]; [StrM appendformat:@ "%@%@--\n", Boundarystr, Randomidstr]; NSLog (@ "%@", StrM); return [StrM copy];} #pragma mark-Upload file-(void) Uploadfilewithurl: (nsurl *) URL data: (NSData *) data{//1> data body nsstring *topstr = [self topstringwithmimetype:@ "Image/png" uploadfile:@ "Avatar 1.png"]; NSString *bottomstr = [self bottomstring]; Nsmutabledata *datam = [Nsmutabledata data]; [Datam appenddata:[topstr datausingencoding:nsutf8stringencoding]; [Datam Appenddata:data]; [Datam appenddata:[bottomstr datausingencoding:nsutf8stringencoding]; 1. Request nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url cachepolicy:0 timeoutInterval:2.0f]; Datam is released when the scope is out, so no copy request is necessary. Httpbody = Datam; 2> set the request Header property request. HttpmethOD = @ "POST"; 3> set content-length nsstring *strlength = [NSString stringwithformat:@ "%ld", (long) datam.length]; [Request Setvalue:strlength forhttpheaderfield:@ "Content-length"]; 4> set Content-type nsstring *strcontenttype = [NSString stringwithformat:@ "multipart/form-data; boundary=%@", Rand OMIDSTR]; [Request Setvalue:strcontenttype forhttpheaderfield:@ "Content-type"]; 3> connection server send request [nsurlconnection sendasynchronousrequest:request Queue:[[nsoperationqueue alloc] init] CompletionHa ndler:^ (Nsurlresponse *response, NSData *data, Nserror *connectionerror) {nsstring *result = [[NSString al LOC] Initwithdata:data encoding:nsutf8stringencoding]; NSLog (@ "%@", result); }];} @end