下載, 上傳與解壓

小文件下載
如果文件比較小躺孝,下載方式會(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

pdf

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) {
   
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吱肌,隨后出現(xiàn)的幾起案子痘拆,更是在濱河造成了極大的恐慌,老刑警劉巖氮墨,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纺蛆,死亡現(xiàn)場(chǎng)離奇詭異吐葵,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)桥氏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)温峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人字支,你說(shuō)我怎么就攤上這事凤藏。” “怎么了堕伪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵清笨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刃跛,道長(zhǎng)抠艾,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任桨昙,我火速辦了婚禮检号,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛙酪。我一直安慰自己齐苛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布桂塞。 她就那樣靜靜地躺著凹蜂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阁危。 梳的紋絲不亂的頭發(fā)上玛痊,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音狂打,去河邊找鬼擂煞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趴乡,可吹牛的內(nèi)容都是我干的对省。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晾捏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒿涎!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惦辛,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤劳秋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體俗批,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俗或,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岁忘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辛慰。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖干像,靈堂內(nèi)的尸體忽然破棺而出帅腌,到底是詐尸還是另有隱情,我是刑警寧澤麻汰,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布速客,位于F島的核電站,受9級(jí)特大地震影響五鲫,放射性物質(zhì)發(fā)生泄漏溺职。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一位喂、第九天 我趴在偏房一處隱蔽的房頂上張望浪耘。 院中可真熱鬧,春花似錦塑崖、人聲如沸七冲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)澜躺。三九已至,卻和暖如春抒蚜,著一層夾襖步出監(jiān)牢的瞬間掘鄙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工削锰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留通铲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓器贩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親朋截。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛹稍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容