ios开发网络学习四:NSURLConnection大文件断点下载

#import "ViewController.h"

@interface ViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;

@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
/** 文件句柄*/
@property (nonatomic, strong)NSFileHandle *handle;
/** 沙盒路径 */
@property (nonatomic, strong) NSString *fullPath;
/** 连接对象 */
@property (nonatomic, strong) NSURLConnection *connect;
@end

@implementation ViewController

- (IBAction)startBtnClick:(id)sender {
    [self download];
}
- (IBAction)cancelBtnClick:(id)sender {
    [self.connect cancel];
}
- (IBAction)goOnBtnClick:(id)sender {
    [self download];
}

//内存飙升
-(void)download
{
    //1.url
    // NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];

    NSURL *url = [NSURL URLWithString:@"http://www.33lc.com/article/UploadPic/2012-10/2012102514201759594.jpg"];

    //2.创建请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //设置请求头信息,告诉服务器值请求一部分数据range
    /*
     bytes=0-100
     bytes=-100
     bytes=0- 请求100之后的所有数据
     */
    NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
    [request setValue:range forHTTPHeaderField:@"Range"];
    NSLog(@"+++++++%@",range);

    //3.发送请求
    NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
    self.connect = connect;
}

#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"didReceiveResponse");

    //1.得到文件的总大小(本次请求的文件数据的总大小 != 文件的总大小)
    // self.totalSize = response.expectedContentLength + self.currentSize;

    if (self.currentSize >0) {
        return;
    }

    self.totalSize = response.expectedContentLength;

    //2.写数据到沙盒中
    self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.jpg"];

    NSLog(@"%@",self.fullPath);

    //3.创建一个空的文件
    [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];

    //NSDictionary *dict = [[NSFileManager defaultManager]attributesOfItemAtPath:self.fullPath error:nil];

    //4.创建文件句柄(指针)
    self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    //1.移动文件句柄到数据的末尾
    [self.handle seekToEndOfFile];

    //2.写数据
    [self.handle writeData:data];

    //3.获得进度
    self.currentSize += data.length;

    //进度=已经下载/文件的总大小
    NSLog(@"%f",1.0 *  self.currentSize/self.totalSize);
    self.progressView.progress = 1.0 *  self.currentSize/self.totalSize;
    //NSLog(@"%@",self.fullPath);
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //1.关闭文件句柄
    [self.handle closeFile];
    self.handle = nil;

    NSLog(@"connectionDidFinishLoading");
    NSLog(@"%@",self.fullPath);
}
@end

#####6.0  大文件断点下载

(1)实现思路

在下载文件的时候不再是整块的从头开始下载,而是看当前文件已经下载到哪个地方,然后从该地方接着往后面下载。可以通过在请求对象中设置请求头实现。

(2)解决方案(设置请求头)

```

//2.创建请求对象

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//2.1 设置下载文件的某一部分

// 只要设置HTTP请求头的Range属性, 就可以实现从指定位置开始下载

/*

表示头500个字节:Range: bytes=0-499

表示第二个500字节:Range: bytes=500-999

表示最后500个字节:Range: bytes=-500

表示500字节以后的范围:Range: bytes=500-

*/

NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentLength];

[request setValue:range forHTTPHeaderField:@"Range"];

```

(3)注意点(下载进度并判断是否需要重新创建文件)

```objc

//获得当前要下载文件的总大小(通过响应头得到)

NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

//注意点:res.expectedContentLength获得是本次请求要下载的文件的大小(并非是完整的文件的大小)

//因此:文件的总大小 == 本次要下载的文件大小+已经下载的文件的大小

self.totalLength = res.expectedContentLength + self.currentLength;

NSLog(@"----------------------------%zd",self.totalLength);

//0 判断当前是否已经下载过,如果当前文件已经存在,那么直接返回

if (self.currentLength >0) {

return;

}

```

时间: 2024-10-18 01:11:38

ios开发网络学习四:NSURLConnection大文件断点下载的相关文章

ios开发网络学习十一:NSURLSessionDataTask离线断点下载(断点续传)

#import "ViewController.h" #define FileName @"121212.mp4" @interface ViewController ()<NSURLSessionDataDelegate> @property (weak, nonatomic) IBOutlet UIProgressView *proessView; /** 接受响应体信息 */ @property (nonatomic, strong) NSFile

ios开发网络学习五:MiMEType ,多线程下载文件思路,文件的压缩和解压缩

一:MiMEType:一般可以再百度上搜索到相应文件的MiMEType,或是利用c语言的api去获取文件的MiMEType : //对该文件发送一个异步请求,拿到文件的MIMEType - (void)MIMEType { //    NSString *file = @"file:///Users/文顶顶/Desktop/test.png"; [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[

使用NSURLConnection实现大文件断点下载

使用NSURLConnection实现大文件断点下载 由于是实现大文件的断点下载,不是下载一般图片什么的.在设计这个类的时候本身就不会考虑把下载的文件缓存到内存中,而是直接写到文件系统. 要实现断点下载,需要满足1个条件,那就是,必须要服务器支持断点下载. 实现的思路是这样子的: 1.  第一次会获取到被下载文件的总大小(服务器提供这个值) 下载文件总大小 = 期望从服务器获取文件的大小 + 本地已经下载的文件的大小 2.  设置请求的缓存策略为不会读取本地中已经缓存的数据(NSURLReque

ios开发网络学习三:NSURLConnection小文件大文件下载

一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> /** 注释 */ @property (nonatomic, strong) NSMutableData *fileData; @property (nonatomic, assign) NSInteger totalSize; @property (weak, nonatomic) IB

ios开发网络学习九:NSURLSessionDownloadTask实现大文件下载

一:NSURLSessionDownloadTask:实现文件下载:无法监听进度 #import "ViewController.h" @interface ViewController () @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self download]; } //优点:不需要担心

ios开发网络学习十:利用文件句柄实现大文件下载

#import "ViewController.h" @interface ViewController ()<NSURLSessionDataDelegate> @property (weak, nonatomic) IBOutlet UIProgressView *proessView; /** 接受响应体信息 */ @property (nonatomic, strong) NSFileHandle *handle; @property (nonatomic, ass

iOS开发RunLoop学习:四:RunLoop的应用和RunLoop的面试题

一:RunLoop的应用 #import "ViewController.h" @interface ViewController () /** 注释 */ @property (nonatomic, strong) NSThread *thread; @end @implementation ViewController /** * 1:用NSThread创建线程的时候,不要忘记调用start方法来开启线程,在一条线程中的任务执行的顺序是同步的,串行执行,并且当线程中的任务执行完毕后

iOS 大文件断点下载

iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"resumeData.tmp"] #import

Android应用开发之使用Socket进行大文件断点上传续传

http://www.linuxidc.com/Linux/2012-03/55567.htm http://blog.csdn.net/shimiso/article/details/8529633/ 在Android中上传文件可以采用HTTP方式,也可以采用Socket方式,但是HTTP方式不能上传大文件,这里介绍一种通过Socket方式来进行断点续传的方式,服务端会记录下文件的上传进度,当某一次上传过程意外终止后,下一次可以继续上传,这里用到的其实还是J2SE里的知识. 这个上传程序的原理