小文件下載
如果文件比較小躺孝,下載方式會(huì)比較多
直接用NSData的+ (id)dataWithContentsOfURL:(NSURL *)url;
利用NSURLConnection發(fā)送一個(gè)HTTP請(qǐng)求(默認(rèn)是get請(qǐng)求)去下載
如果是下載圖片窘拯,還可以利用SDWebImage框架
如果是大文件下載,建議使用或者使用NSURLSession第三方框架
HTTP Range的示例
通過(guò)設(shè)置請(qǐng)求頭Range可以指定位置每次從網(wǎng)路下載數(shù)據(jù)包的大小
Range示例
bytes=0-499 從0到499的頭500個(gè)字節(jié)
bytes=500-999 從500到999的第二個(gè)500字節(jié)
bytes=500- 從500字節(jié)以后的所有字節(jié)
bytes=-500 最后500個(gè)字節(jié)
bytes=500-599,800-899 同時(shí)指定幾個(gè)范圍
Range小結(jié)
- 用于分隔
前面的數(shù)字表示起始字節(jié)數(shù)
后面的數(shù)組表示截止字節(jié)數(shù),沒(méi)有表示到末尾
, 用于分組泉懦,可以一次指定多個(gè)Range,不過(guò)很少用
第三方解壓縮框架——SSZipArchive
下載地址:https://github.com/samsoffes/ssziparchive
注意:需要引入libz.dylib框架
Unzipping
NSString *zipPath = @"path_to_your_zip_file";
NSString *destinationPath = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
Zipping
NSString *zippedPath = @"path_where_you_want_the_file_created";
NSArray *inputPaths = [NSArray arrayWithObjects:
[[NSBundle mainBundle] pathForResource:@"photo1" ofType:@"jpg"],
[[NSBundle mainBundle] pathForResource:@"photo2" ofType:@"jpg"]
nil];
[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
第三方解壓縮框架——ZipArchive
下載地址:https://github.com/ZipArchive/ZipArchive
需要引入libz.dylib框架
導(dǎo)入頭文件Main.h
創(chuàng)建壓縮文件
+ (BOOL)createZipFileAtPath:(NSString *)path
withFilesAtPaths:(NSArray *)paths;
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath;
解壓
+ (BOOL)unzipFileAtPath:(NSString *)path
toDestination:(NSString *)destination
文件上傳的步驟
設(shè)置請(qǐng)求頭
[request setValue:@"multipart/form-data; boundary=分割線"forHTTPHeaderField:@"Content-Type"];
設(shè)置請(qǐng)求體
非文件參數(shù)
--分割線\r\n
Content-Disposition: form-data; name="參數(shù)名"\r\n
\r\n
參數(shù)值
\r\n
文件參數(shù)
--分割線\r\n
Content-Disposition: form-data; name="參數(shù)名"; filename="文件名"\r\n
Content-Type: 文件的MIMEType\r\n
\r\n
文件數(shù)據(jù)
\r\n
參數(shù)結(jié)束的標(biāo)記
--分割線--\r\n
multipart/form-data格式小結(jié)
[圖片上傳中疹瘦。崩哩。。(1)]
部分文件的MIMEType
類(lèi)型
文件拓展名
MIMEType
圖片
png
image/png
bmp\dib
image/bmp
jpe\jpeg\jpg
image/jpeg
gif
image/gif
多媒體
mp3
audio/mpeg
mp4\mpg4\m4vmp4v
video/mp4
文本
js
application/javascript
application/pdf
text\txt
text/plain
json
application/json
xml
text/xml
獲得文件的MIMEType
利用NSURLConnection
- (NSString *)MIMEType:(NSURL *)url
{
1.創(chuàng)建一個(gè)請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
2.發(fā)送請(qǐng)求(返回響應(yīng))
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
3.獲得MIMEType
return response.MIMEType;
}
獲得文件的MIMEType
C語(yǔ)言API
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path
{
if (![[NSFileManager alloc] init] fileExistsAtPath:path]) {
return nil;
}
CFStringRef UTI =
UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(CFStringRef)[path pathExtension], NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI,
kUTTagClassMIMEType);
CFRelease(UTI);
if (!MIMEType) {
return @"application/octet-stream";
}
return NSMakeCollectable(MIMEType);
}
1.0 文件下載
- 1.1 小文件下載
(1)第一種方式(NSData)
使用NSDta直接加載網(wǎng)絡(luò)上的url資源(不考慮線程)
-(void)dataDownload
{
1.確定資源路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
2.根據(jù)URL加載對(duì)應(yīng)的資源
NSData *data = [NSData dataWithContentsOfURL:url];
3.轉(zhuǎn)換并顯示數(shù)據(jù)
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
}
(2)第二種方式(NSURLConnection-sendAsync)
使用NSURLConnection發(fā)送異步請(qǐng)求下載文件資源
-(void)connectDownload
{
1.確定請(qǐng)求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
2.創(chuàng)建請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.使用NSURLConnection發(fā)送一個(gè)異步請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
4.拿到并處理數(shù)據(jù)
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
}]言沐;
}
(3)第三種方式(NSURLConnection-delegate)
使用NSURLConnection設(shè)置代理發(fā)送異步請(qǐng)求的方式下載文件
-(void)connectionDelegateDownload
{
1.確定請(qǐng)求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
2.創(chuàng)建請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.使用NSURLConnection設(shè)置代理并發(fā)送異步請(qǐng)求
[NSURLConnection connectionWithRequest:request delegate:self];
}
#pragma mark--NSURLConnectionDataDelegate
當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用邓嘹,該方法只會(huì)調(diào)用一次
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
創(chuàng)建一個(gè)容器,用來(lái)接收服務(wù)器返回的數(shù)據(jù)
self.fileData = [NSMutableData data];
獲得當(dāng)前要下載文件的總大邢找取(通過(guò)響應(yīng)頭得到)
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
self.totalLength = res.expectedContentLength;
NSLog(@"%zd",self.totalLength);
拿到服務(wù)器端推薦的文件名稱(chēng)
self.fileName = res.suggestedFilename;
}
當(dāng)接收到服務(wù)器返回的數(shù)據(jù)時(shí)會(huì)調(diào)用
該方法可能會(huì)被調(diào)用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
拼接每次下載的數(shù)據(jù)
[self.fileData appendData:data];
計(jì)算當(dāng)前下載進(jìn)度并刷新UI顯示
self.currentLength = self.fileData.length;
NSLog(@"%f",1.0* self.currentLength/self.totalLength);
self.progressView.progress = 1.0* self.currentLength/self.totalLength;
}
當(dāng)網(wǎng)絡(luò)請(qǐng)求結(jié)束之后調(diào)用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
文件下載完畢把接受到的文件數(shù)據(jù)寫(xiě)入到沙盒中保存
1.確定要保存文件的全路徑
caches文件夾路徑
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
2.寫(xiě)數(shù)據(jù)到文件中
[self.fileData writeToFile:fullPath atomically:YES];
NSLog(@"%@",fullPath);
}
當(dāng)請(qǐng)求失敗的時(shí)候調(diào)用該方法
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%s",__func__);
}
- 3.2 大文件的下載
(1)實(shí)現(xiàn)思路
邊接收數(shù)據(jù)邊寫(xiě)文件以解決內(nèi)存越來(lái)越大的問(wèn)題
(2)核心代碼
當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用汹押,該方法只會(huì)調(diào)用一次
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
0.獲得當(dāng)前要下載文件的總大小(通過(guò)響應(yīng)頭得到)
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
self.totalLength = res.expectedContentLength;
NSLog(@"%zd",self.totalLength);
創(chuàng)建一個(gè)新的文件起便,用來(lái)當(dāng)接收到服務(wù)器返回?cái)?shù)據(jù)的時(shí)候往該文件中寫(xiě)入數(shù)據(jù)
1.獲取文件管理者
NSFileManager *manager = [NSFileManager defaultManager];
2.拼接文件的全路徑
caches文件夾路徑
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *fullPath = [caches stringByAppendingPathComponent:res.suggestedFilename];
self.fullPath = fullPath;
3.創(chuàng)建一個(gè)空的文件
[manager createFileAtPath:fullPath contents:nil attributes:nil];
}
當(dāng)接收到服務(wù)器返回的數(shù)據(jù)時(shí)會(huì)調(diào)用
該方法可能會(huì)被調(diào)用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
1.創(chuàng)建一個(gè)用來(lái)向文件中寫(xiě)數(shù)據(jù)的文件句柄
注意當(dāng)下載完成之后棚贾,該文件句柄需要關(guān)閉,調(diào)用closeFile方法
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
2.設(shè)置寫(xiě)數(shù)據(jù)的位置(追加)
[handle seekToEndOfFile];
3.寫(xiě)數(shù)據(jù)
[handle writeData:data];
4.計(jì)算當(dāng)前文件的下載進(jìn)度
self.currentLength += data.length;
NSLog(@"%f",1.0* self.currentLength/self.totalLength);
self.progressView.progress = 1.0* self.currentLength/self.totalLength;
}
- 1.3 大文件斷點(diǎn)下載
(1)實(shí)現(xiàn)思路
在下載文件的時(shí)候不再是整塊的從頭開(kāi)始下載缨睡,而是看當(dāng)前文件已經(jīng)下載到哪個(gè)地方鸟悴,然后從該地方接著往后面下載〗蹦辏可以通過(guò)在請(qǐng)求對(duì)象中設(shè)置請(qǐng)求頭實(shí)現(xiàn)细诸。
(2)解決方案(設(shè)置請(qǐng)求頭)
2.創(chuàng)建請(qǐng)求對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
2.1 設(shè)置下載文件的某一部分
只要設(shè)置HTTP請(qǐng)求頭的Range屬性, 就可以實(shí)現(xiàn)從指定位置開(kāi)始下載
表示頭500個(gè)字節(jié):Range: bytes=0-499
表示第二個(gè)500字節(jié):Range: bytes=500-999
表示最后500個(gè)字節(jié):Range: bytes=-500
表示500字節(jié)以后的范圍:Range: bytes=500-
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentLength];
[request setValue:range forHTTPHeaderField:@"Range"];
(3)注意點(diǎn)(下載進(jìn)度并判斷是否需要重新創(chuàng)建文件)
獲得當(dāng)前要下載文件的總大小(通過(guò)響應(yīng)頭得到)
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
注意點(diǎn):res.expectedContentLength獲得是本次請(qǐng)求要下載的文件的大新亍(并非是完整的文件的大姓鸸蟆)
因此:文件的總大小 == 本次要下載的文件大小+已經(jīng)下載的文件的大小
self.totalLength = res.expectedContentLength + self.currentLength;
NSLog(@"----------------------------%zd",self.totalLength);
0 判斷當(dāng)前是否已經(jīng)下載過(guò)利赋,如果當(dāng)前文件已經(jīng)存在,那么直接返回
if (self.currentLength >0) {
return;
}
- 1.4 輸出流
(1)使用輸出流也可以實(shí)現(xiàn)和NSFileHandle相同的功能
(2)如何使用
1.創(chuàng)建一個(gè)數(shù)據(jù)輸出流
第一個(gè)參數(shù):二進(jìn)制的流數(shù)據(jù)要寫(xiě)入到哪里
第二個(gè)參數(shù):采用什么樣的方式寫(xiě)入流數(shù)據(jù)猩系,如果YES則表示追加媚送,如果是NO則表示覆蓋
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];
只要調(diào)用了該方法就會(huì)往文件中寫(xiě)數(shù)據(jù)
如果文件不存在,那么會(huì)自動(dòng)的創(chuàng)建一個(gè)
[stream open];
self.stream = stream;
2.當(dāng)接收到數(shù)據(jù)的時(shí)候?qū)憯?shù)據(jù)
使用輸出流寫(xiě)數(shù)據(jù)
第一個(gè)參數(shù):要寫(xiě)入的二進(jìn)制數(shù)據(jù)
第二個(gè)參數(shù):要寫(xiě)入的數(shù)據(jù)的大小
[self.stream write:data.bytes maxLength:data.length];
3.當(dāng)文件下載完畢的時(shí)候關(guān)閉輸出流
關(guān)閉輸出流
[self.stream close];
self.stream = nil;
- 1.5 使用多線程下載文件思路
01 開(kāi)啟多條線程寇甸,每條線程都只下載文件的一部分(通過(guò)設(shè)置請(qǐng)求頭中的Range來(lái)實(shí)現(xiàn))
02 創(chuàng)建一個(gè)和需要下載文件大小一致的文件塘偎,判斷當(dāng)前是那個(gè)線程,根據(jù)當(dāng)前的線程來(lái)判斷下載的數(shù)據(jù)應(yīng)該寫(xiě)入到文件中的哪個(gè)位置拿霉。(假設(shè)開(kāi)5條線程來(lái)下載10M的文件吟秩,那么線程1下載0-2M,線程2下載2-4M一次類(lèi)推绽淘,當(dāng)接收到服務(wù)器返回的數(shù)據(jù)之后應(yīng)該先判斷當(dāng)前線程是哪個(gè)線程涵防,假如當(dāng)前線程是線程2,那么在寫(xiě)數(shù)據(jù)的時(shí)候就從文件的2M位置開(kāi)始寫(xiě)入)
03 代碼相關(guān):使用NSFileHandle這個(gè)類(lèi)的seekToFileOfSet方法沪铭,來(lái)向文件中特定的位置寫(xiě)入數(shù)據(jù)壮池。
04 技術(shù)相關(guān)
a.每個(gè)線程通過(guò)設(shè)置請(qǐng)求頭下載文件中的某一個(gè)部分
b.通過(guò)NSFileHandle向文件中的指定位置寫(xiě)數(shù)據(jù)
2.0 文件的壓縮和解壓縮
(1)說(shuō)明
使用ZipArchive來(lái)壓縮和解壓縮文件需要添加依賴(lài)庫(kù)(libz),使用需要包含Main文件,如果使用cocoaPoads來(lái)安裝框架杀怠,那么會(huì)自動(dòng)的配置框架的使用環(huán)境
(2)相關(guān)代碼
壓縮文件的第一種方式
第一個(gè)參數(shù):壓縮文件要保存的位置
第二個(gè)參數(shù):要壓縮哪幾個(gè)文件
[Main createZipFileAtPath:fullpath withFilesAtPaths:arrayM];
壓縮文件的第二種方式
第一個(gè)參數(shù):文件壓縮到哪個(gè)地方
第二個(gè)參數(shù):要壓縮文件的全路徑
[Main createZipFileAtPath:fullpath withContentsOfDirectory:zipFile];
如何對(duì)壓縮文件進(jìn)行解壓
第一個(gè)參數(shù):要解壓的文件
第二個(gè)參數(shù):要解壓到什么地方
[Main unzipFileAtPath:unZipFile toDestination:fullpath];
2.0 文件的上傳
- 2.1 文件上傳步驟
(1)確定請(qǐng)求路徑
(2)根據(jù)URL創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
(3)設(shè)置請(qǐng)求對(duì)象椰憋,修改請(qǐng)求方式為POST
(4)設(shè)置請(qǐng)求頭,告訴服務(wù)器我們將要上傳文件(Content-Type)
(5)設(shè)置請(qǐng)求體(在請(qǐng)求體中按照既定的格式拼接要上傳的文件參數(shù)和非文件參數(shù)等數(shù)據(jù))
001 拼接文件參數(shù)
002 拼接非文件參數(shù)
003 添加結(jié)尾標(biāo)記
(6)使用NSURLConnection sendAsync發(fā)送異步請(qǐng)求上傳文件
(7)解析服務(wù)器返回的數(shù)據(jù)
- 2.2 文件上傳設(shè)置請(qǐng)求體的數(shù)據(jù)格式
請(qǐng)求體拼接格式
分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c
01.文件參數(shù)拼接格式
--分隔符
Content-Disposition:參數(shù)
Content-Type:參數(shù)
空行
文件參數(shù)
02.非文件拼接參數(shù)
--分隔符
Content-Disposition:參數(shù)
空行
非文件的二進(jìn)制數(shù)據(jù)
03.結(jié)尾標(biāo)識(shí)
--分隔符--
2.3 文件上傳相關(guān)代碼
-
(void)upload
{
1.確定請(qǐng)求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];2.創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];3.設(shè)置請(qǐng)求方式為POST
request.HTTPMethod = @"POST";4.設(shè)置請(qǐng)求頭
NSString *filed = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:filed forHTTPHeaderField:@"Content-Type"];5.設(shè)置請(qǐng)求體
NSMutableData *data = [NSMutableData data];
5.1 文件參數(shù)--分隔符
Content-Disposition:參數(shù)
Content-Type:參數(shù)
空行
文件參數(shù)[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\"" dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; [data appendData:KnewLine]; [data appendData:KnewLine]; UIImage *image = [UIImage imageNamed:@"test"]; NSData *imageData = UIImagePNGRepresentation(image); [data appendData:imageData]; [data appendData:KnewLine];
5.2 非文件參數(shù)
--分隔符
Content-Disposition:參數(shù)
空行
非文件參數(shù)的二進(jìn)制數(shù)據(jù)[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; [data appendData:KnewLine]; [data appendData:KnewLine]; NSData *nameData = [@"wendingding" dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:nameData]; [data appendData:KnewLine]; 5.3 結(jié)尾標(biāo)識(shí) --分隔符-- [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:KnewLine]; request.HTTPBody = data; 6.發(fā)送請(qǐng)求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) { 7.解析服務(wù)器返回的數(shù)據(jù) NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]); }];
}
- 2.4 如何獲得文件的MIMEType類(lèi)型
(1)直接對(duì)該對(duì)象發(fā)送一個(gè)異步網(wǎng)絡(luò)請(qǐng)求驮肉,在響應(yīng)頭中通過(guò)response.MIMEType拿到文件的MIMEType類(lèi)型
如果想要及時(shí)拿到該數(shù)據(jù)熏矿,那么可以發(fā)送一個(gè)同步請(qǐng)求
-
(NSString *)getMIMEType
{
NSString *filePath = @"/Users/文頂頂/Desktop/備課/其它/swift.md";NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]] returningResponse:&response error:nil];
return response.MIMEType;
}
對(duì)該文件發(fā)送一個(gè)異步請(qǐng)求已骇,拿到文件的MIMEType
-
(void)MIMEType
{NSString *file = @"file:///Users/Edison/Desktop/test.png";
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"/Users/Edison/Desktop/test.png"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
NSLog(@"%@",response.MIMEType);
}];
}
(2)通過(guò)UTTypeCopyPreferredTagWithClass方法
注意:需要依賴(lài)于框架MobileCoreServices
-
(NSString *)mimeTypeForFileAtPath:(NSString *)path
{
if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {
return nil;
}CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
CFRelease(UTI);
if (!MIMEType) {
return @"application/octet-stream";
}
return (__bridge NSString *)(MIMEType);
}
****************************************************************
**************************筆記****************************
一离钝、大文件下載
1.方案:利用NSURLConnection和它的代理方法
1> 發(fā)送一個(gè)請(qǐng)求
1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
2.請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.下載(創(chuàng)建完conn對(duì)象后,會(huì)自動(dòng)發(fā)起一個(gè)異步請(qǐng)求)
[NSURLConnection connectionWithRequest:request delegate:self];
2> 在代理方法中處理服務(wù)器返回的數(shù)據(jù)
在接收到服務(wù)器的響應(yīng)時(shí):
1.創(chuàng)建一個(gè)空的文件
2.用一個(gè)句柄對(duì)象關(guān)聯(lián)這個(gè)空的文件褪储,目的是:方便后面用句柄對(duì)象往文件后面寫(xiě)數(shù)據(jù)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
文件路徑
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];
創(chuàng)建一個(gè)空的文件 到 沙盒中
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr createFileAtPath:filepath contents:nil attributes:nil];
創(chuàng)建一個(gè)用來(lái)寫(xiě)數(shù)據(jù)的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}
在接收到服務(wù)器返回的文件數(shù)據(jù)時(shí)卵渴,利用句柄對(duì)象往文件的最后面追加數(shù)據(jù)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
移動(dòng)到文件的最后面
[self.writeHandle seekToEndOfFile];
將數(shù)據(jù)寫(xiě)入沙盒
[self.writeHandle writeData:data];
}
在所有數(shù)據(jù)接收完畢時(shí),關(guān)閉句柄對(duì)象
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
關(guān)閉文件
[self.writeHandle closeFile];
self.writeHandle = nil;
}
2.注意點(diǎn):千萬(wàn)不能用NSMutableData來(lái)拼接服務(wù)器返回的數(shù)據(jù)
二鲤竹、NSURLConnection發(fā)送異步請(qǐng)求的方法
1.block形式- 除開(kāi)大文件下載以外的操作浪读,都可以用這種形式
[NSURLConnection sendAsynchronousRequest:<#(NSURLRequest *)#> queue:<#(NSOperationQueue *)#> completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
}];
2.代理形式- 一般用在大文件下載
1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123"];
2.請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.下載(創(chuàng)建完conn對(duì)象后,會(huì)自動(dòng)發(fā)起一個(gè)異步請(qǐng)求)
[NSURLConnection connectionWithRequest:request delegate:self];
三辛藻、NSURLSession
1.使用步驟
1> 獲得NSURLSession對(duì)象
2> 利用NSURLSession對(duì)象創(chuàng)建對(duì)應(yīng)的任務(wù)(Task)
3> 開(kāi)始任務(wù)([task resume])
2.獲得NSURLSession對(duì)象
1> [NSURLSession sharedSession]
2>
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];
3.任務(wù)類(lèi)型
1> NSURLSessionDataTask
* 用途:用于非文件下載的GET\POST請(qǐng)求
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
2> NSURLSessionDownloadTask
* 用途:用于文件下載(小文件碘橘、大文件)
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
}];