大文件下载

@interface HMViewController () <NSURLConnectionDataDelegate>

/**

 *  用来写数据的文件句柄对象

 */

@property (nonatomic, strong) NSFileHandle *writeHandle;

/**

 *  文件的总大小

 */

@property (nonatomic, assign) long long totalLength;

/**

 *  当前已经写入的文件大小

 */

@property (nonatomic, assign) long long currentLength;

 

@property (nonatomic, weak) DACircularProgressView *circleView;

@end

 

@implementation HMViewController

 

- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    

    DACircularProgressView *circleView = [[DACircularProgressView alloc] init];

    circleView.frame = CGRectMake(100, 50, 100, 100);

    circleView.progressTintColor = [UIColor redColor];

    circleView.trackTintColor = [UIColor blueColor];

    circleView.progress = 0.01;

    [self.view addSubview:circleView];

    self.circleView = circleView;

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    // 1.URL

    NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/music.zip"];

    

    // 2.请求

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    

    // 3.下载(创建完conn对象后,会自动发起一个异步请求)

    [NSURLConnection connectionWithRequest:request delegate:self];

}

 

#pragma mark - NSURLConnectionDataDelegate代理方法

/**

 *  请求失败时调用(请求超时、网络异常)

 *

 *  @param error      错误原因

 */

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

{

    NSLog(@"didFailWithError");

}

 

/**

 *  1.接收到服务器的响应就会调用

 *

 *  @param response   响应

 */

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

    // 文件路径

    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

    NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];

    

    // 创建一个空的文件 沙盒中

    NSFileManager *mgr = [NSFileManager defaultManager];

    [mgr createFileAtPath:filepath contents:nil attributes:nil];

    

    // 创建一个用来写数据的文件句柄

    self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];

    

    // 获得文件的总大小

    self.totalLength = response.expectedContentLength;

}

 

/**

 *  2.当接收到服务器返回的实体数据时调用(具体内容,这个方法可能会被调用多次)

 *

 *  @param data       这次返回的数据

 */

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    // 移动到文件的最后面

    [self.writeHandle seekToEndOfFile];

    

    // 将数据写入沙盒

    [self.writeHandle writeData:data];

    

    // 累计文件的长度

    self.currentLength += data.length;

    

    NSLog(@"下载进度:%f", (double)self.currentLength/ self.totalLength);

    self.circleView.progress = (double)self.currentLength/ self.totalLength;

}

 

/**

 *  3.加载完毕后调用(服务器的数据已经完全返回后)

 */

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    self.currentLength = 0;

    self.totalLength = 0;

    

    // 关闭文件

    [self.writeHandle closeFile];

    self.writeHandle = nil;

}

@end

a:NSFileHandle只能打开现成的文件,所以如果是新文件则需要NSFileManager先创建新文件;

b:打开一个文件就后,就需要关闭一个文件;

c:根据不同的要求可能要设定不同的偏移量(即光标所在位置),可以通过移动到开头或结尾,也可以先获取当前位置然后增加和减少多少字节来移动;

d:文件路径是NSString对象,可以用 stringByAppendingPathComponent+文件全称 方法构造一个完整的文件路径;

e:往文件里面写的内容是NSData,如果是其他的格式则可以用 dataUsingEncoding : NSUTF8StringEncoding 来转化成data类型;

f:同样,目录的写法于Linux类似,~家目录,/根目录,.当前目录,..父目录,用/表示层级等。

(1)NSFileManager(详见:http://blog.csdn.net/enuola/article/details/7797055)

原文地址:https://www.cnblogs.com/seeworld/p/6013293.html