由于项目需要下载一些文件,结合以前写的图片缓存:http://blog.csdn.net/marujunyy/article/details/8538679
用ASIHttpRequest 封装了一个文件下载类:支持断点续传、缓存到Document文件夹。
使用方法:
在.h文件里 #import"AsyncFileBuffer.h" 并添加代理:AsyncFileDelegate
AsyncFileBuffer *asyncBuffer = [[AsyncFileBuffer alloc] init];
asyncBuffer.delegate = self;
[asyncBuffer loadFileFromURLString:@"http://file.easymorse.com/app/sxhm/RemoteNotificationsPG.pdf"];
#pragma mark - AsyncFileDelegate
- (void)asyncBufferSuccess:(AsyncFileBuffer *)buffer fileLocationPath:(NSString *)locPath
{
//locPath 下载的文件在本地的路径
}
- (void)asyncBuffer:(AsyncFileBuffer *)buffer progress:(float)progress fileSize:(uint)fileSize rate:(NSString *)rate
{
//下载进度:如果已下载到本地 该方法不会被调用
NSString *downSize = [buffer formatFileSize:fileSize*progress];
NSLog(@"已下载:%@ 文件大小:%@",downSize,[buffer formatFileSize:fileSize]);
NSLog(@"进度:%.2f%% 下载速度:%@",progress*100,rate);
}
- (void)asyncBufferFailed:(AsyncFileBuffer *)buffer
{
NSLog(@"error : %@",buffer.error);
}
AsyncFileBuffer.h
//
// AsyncFileBuffer.h
//
// Created by marujun on 13-9-8.
// Copyright (c) 2013年 极致. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ASIFormDataRequest.h"
@class AsyncFileBuffer;
@protocol AsyncFileDelegate <NSObject>
- (void)asyncBuffer:(AsyncFileBuffer *)buffer progress:(float)progress fileSize:(uint)fileSize rate:(NSString *)rate;
- (void)asyncBufferSuccess:(AsyncFileBuffer *)buffer fileLocationPath:(NSString *)locPath;
- (void)asyncBufferFailed:(AsyncFileBuffer *)buffer;
@end
@interface AsyncFileBuffer : NSObject<ASIHTTPRequestDelegate>
{
__block uint fileSize; //以B为单位,文件大小
__block uint completedSize; //已下载文件的大小
NSDate *startTime;
}
@property (nonatomic,assign) int tag;
@property (nonatomic,retain) id<AsyncFileDelegate> delegate;
@property (nonatomic,retain) NSURL *downloadURL;
@property (nonatomic,retain) NSString *originalUrlString; //未做处理的url字符串
@property (nonatomic,retain) ASIHTTPRequest *request;
@property (nonatomic,retain) NSError *error;
- (void)loadFileFromURLString:(NSString *)urlStr;
- (void)pauseDownload; //暂停下载
- (void)resumeDownload; //继续下载
- (NSString *)formatFileSize:(unsigned long long)size; //转换B为K、M、G、T
@end
AsyncFileBuffer.m
//
// AsyncFileBuffer.m
//
// Created by marujun on 13-9-8.
// Copyright (c) 2013年 极致. All rights reserved.
//
#import "AsyncFileBuffer.h"
@implementation AsyncFileBuffer
@synthesize request = _request;
@synthesize error = _error;
@synthesize delegate = _delegate;
@synthesize downloadURL = _downloadURL;
@synthesize originalUrlString = _originalUrlString;
@synthesize tag = _tag;
- (void)dealloc
{
[_error release];
[_request release];
[_delegate release];
[super dealloc];
}
- (void)loadFileFromURLString:(NSString *)urlStr
{
self.originalUrlString = urlStr;
_downloadURL = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if(_downloadURL!=nil&&![_downloadURL isEqual:@""]) {
if ([self isExistsFile:[_downloadURL description]]) {
//返回数据
if ([self.delegate respondsToSelector:@selector(asyncBufferSuccess:fileLocationPath:)]) {
[self.delegate asyncBufferSuccess:self fileLocationPath:[self getFilePathWithURL:[_downloadURL description]]];
}
}else{
[self retain];
[self createDirectoryWithUrl:_downloadURL];
[self resumeDownload];
}
}
}
- (void)pauseDownload
{
[_request clearDelegatesAndCancel];
}
- (void)resumeDownload
{
NSString *downloadPath = [self getFilePathWithURL:[_downloadURL description]];
_request = [[ASIHTTPRequest alloc] initWithURL:_downloadURL];
_request.downloadDestinationPath = [self getFilePathWithURL:[_downloadURL description]]; //现在下载文件路径
_request.temporaryFileDownloadPath = [downloadPath stringByAppendingString:@".temp"]; //临时路径
_request.allowResumeForFileDownloads = YES; //设置支持断点续传
_request.downloadProgressDelegate = self; //进度显示
_request.delegate = self;
[_request startAsynchronous];
}
- (void)createDirectoryWithUrl:(NSURL *)url
{
fileSize = 0;
//如果不存在则创建,因为asi下载时,不会自动创建文件夹
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *folderPath = [self getFilePathWithURL:[url description]];
NSRange range = [folderPath rangeOfString:@"/" options:NSBackwardsSearch];
folderPath = [folderPath substringToIndex:range.location];
BOOL fileExists = [fileManager fileExistsAtPath:folderPath];
if (!fileExists) {
[fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
}
#pragma mark - ASIHTTPRequestDelegate
- (void)requestStarted:(ASIHTTPRequest *)request
{
startTime = [[NSDate date] retain];
completedSize = 0.0;
}
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
fileSize = request.contentLength;
// fileSize = [[responseHeaders valueForKey:@"Content-Length"] floatValue];
}
- (void)setProgress:(float)newProgress
{
double deltaTime = [[NSDate date] timeIntervalSinceDate:startTime];
double downSize = (newProgress*fileSize-completedSize)/deltaTime;
NSString *rate = [NSString stringWithFormat:@"%@/S",[self formatFileSize:downSize]];
completedSize = newProgress*fileSize;
startTime = [[NSDate date] retain];
if ([self.delegate respondsToSelector:@selector(asyncBuffer:progress:fileSize:rate:)]) {
[self.delegate asyncBuffer:self progress:newProgress fileSize:fileSize rate:rate];
}
}
-(void)requestFailed:(ASIHTTPRequest *)request
{
// NSLog(@"requestFailed error %@",request.error);
self.error = request.error;
if ([self.delegate respondsToSelector:@selector(asyncBufferFailed:)]) {
[self.delegate asyncBufferFailed:self];
}
[self release];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
if ([self isExistsFile:[_downloadURL description]]) {
if ([self.delegate respondsToSelector:@selector(asyncBufferSuccess:fileLocationPath:)]) {
[self.delegate asyncBufferSuccess:self fileLocationPath:[self getFilePathWithURL:[_downloadURL description]]];
}
}else{
self.error = [[NSError alloc]initWithDomain:@"AsyncFileBuffer" code:1211 userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:@"下载的文件不存在!",NSLocalizedDescriptionKey, nil]];
if ([self.delegate respondsToSelector:@selector(asyncBufferFailed:)]) {
[self.delegate asyncBufferFailed:self];
}
}
[self release];
}
- (BOOL)isExistsFile:(NSString *)fileURL
{
NSFileManager *filemanage = [NSFileManager defaultManager];
NSArray *array=[fileURL componentsSeparatedByString:@"//"];
return [filemanage fileExistsAtPath:[self getCacheFilePath:[array lastObject]]];
}
- (NSString *)getFilePathWithURL:(NSString*)fileURL
{
NSArray *array=[fileURL componentsSeparatedByString:@"//"];
return [self getCacheFilePath:[array lastObject]];
}
- (NSString *)getCacheFilePath:(NSString *)filename
{
filename = [NSString stringWithFormat:@"BufferedFile/%@",filename];
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [documentDir stringByAppendingPathComponent:filename];
return filePath;
}
- (NSString *)formatFileSize:(unsigned long long)size
{
NSString *formattedStr = nil;
if (size == 0){
formattedStr = @"0 B";
}else if (size > 0 && size < 1024){
formattedStr = [NSString stringWithFormat:@"%qu B", size];
}else if (size >= 1024 && size < pow(1024, 2)){
formattedStr = [NSString stringWithFormat:@"%.1f KB", (size / 1024.)];
}else if (size >= pow(1024, 2) && size < pow(1024, 3)){
formattedStr = [NSString stringWithFormat:@"%.2f MB", (size / pow(1024, 2))];
}else if (size >= pow(1024, 3) && size < pow(1024, 4)){
formattedStr = [NSString stringWithFormat:@"%.3f GB", (size / pow(1024, 3))];
}else if (size >= pow(1024, 4)){
formattedStr = [NSString stringWithFormat:@"%.4f TB", (size / pow(1024, 4))];
}
return formattedStr;
}
@end