IOS文件的上传与下载(一)

45 篇文章 0 订阅
分两篇博文来记录文件的上传与下载,首先来说IOS文件的上传,下篇博文说文件的下载
上传文件我们需要处理服务端与客户端,在服务端使用asp.net实现,在客户端使用Objective - C实现

    首先我们来说客户端,代码如下

        private String UPLOAD_PATH = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["UploadPath"]);
        private const int BUFFER_LEN = 8192;
        /// <summary>
        /// 生成文件名的前缀
        /// </summary>
        /// <returns></returns>
        private string GenerateFileName()
        {
            String filename = String.Empty;
            filename = DateTime.Now.ToString("yyyyMMddHHmmsssss");
            filename = String.Format("{0}{1}", System.Guid.NewGuid().ToString(), filename);
            return filename;
        }

        
        public void ProcessRequest(HttpContext context)
        {
            string filename = context.Request.Headers["filename"];
            if (string.IsNullOrEmpty(filename))
            {
                HandlerFileUploadFile(context);
            }
            else
            {
                HandlerHeaderUploadFile(context);
            }
        }
        /// <summary>
        /// 通过 HTTP协议的Headers获取文件名,然后通过context.Request.InputStream 保存文件
        /// </summary>
        /// <param name="context"></param>
        private void HandlerHeaderUploadFile(HttpContext context)
        {
            context.Response.Clear();
            context.Response.ClearHeaders();
            context.Response.AddHeader(@"content-type", @"text/json");
            byte[] buffer = new byte[BUFFER_LEN];
            String filename = context.Request.Headers["filename"];
            filename = String.Format("{0}_{1}", GenerateFileName(), filename);
            String fullfilename = String.Format("{0}{1}",UPLOAD_PATH,filename);
            try
            {
                using(FileStream fs = new FileStream(fullfilename,FileMode.Create,FileAccess.Write,FileShare.None))
                {
                    int length = 0;
                    while ((length = context.Request.InputStream.Read(buffer,0,BUFFER_LEN)) > 0)
                    {
                        fs.Write(buffer, 0, length);
                    }
                }
                context.Response.Write("{\"result\":\"success\",\"message\":\"\"}");
            }
            catch (Exception ex)
            {
                context.Response.Write("{\"result\":\"failed\",\"message\":\""+ex.Message+"\"}");
            }
        }
        /// <summary>
        /// 通过context.Request.Files与HttpPostedFile另存文件
        /// </summary>
        /// <param name="context"></param>
        private void HandlerFileUploadFile(HttpContext context)
        {
            context.Response.ClearHeaders();
            context.Response.Clear();
            context.Response.StatusCode = 200;
            try
            {
                //在上传的时候需要设置Content-Disposition
                if (context.Request.Files != null && context.Request.Files.Count > 0)
                {
                    HttpPostedFile file = context.Request.Files[0];
                    String filename = file.FileName;
                    filename = String.Format("{0}_{1}", GenerateFileName(), filename);
                    String fullfilename = String.Format("{0}{1}", UPLOAD_PATH, filename);
                    file.SaveAs(fullfilename);
                }
                context.Response.Write("{\"result\":\"success\",\"message\":\"\"}");
            }
            catch (Exception ex)
            {
                context.Response.Write("{\"result\":\"failed\",\"message\":\"" + ex.Message + "\"}");
            }
        }
        
    客户端代码如下:
定义一些常用变量
NSString* const kFormBoundary = @"+++++formBoundary";
NSString* const uploadurl = @"http://192.168.18.113/webdownloadupload/uploadfile.ashx";
NSString* const downloadurl = @"http://192.168.18.113/webdownloadupload/downloadfile.ashx";
NSString* const fileKey = @"file";
NSString* const mimeType= @"text/plain";
    
    
    #pragma mark 上传文件一(对应服务端的HandlerFileUploadFile方法处理)
-(void)BtnUploadFileMannerOne:(id)sender{
    

    NSArray *patharray =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//测试的时候需要在Document目录下面放的文件

    NSString *uploadfilepath = [[patharray objectAtIndex:0] stringByAppendingPathComponent:@"20141210162800018-1905642375.rar"];
    NSData *fileData = [NSData dataWithContentsOfFile:uploadfilepath];
    NSString *fileName =[uploadfilepath lastPathComponent];
    
    NSURL *UrlServer =[NSURL URLWithString:uploadurl];
    
    NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:UrlServer];
    [request setHTTPMethod:@"POST"];
    NSString *contentType =[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    
    NSData* formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* postBodyBeforeFile = [NSMutableData data];
    [postBodyBeforeFile appendData:formBoundaryData];
    
    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
    if (mimeType != nil) {
        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
    }
    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Length: %lu\r\n\r\n", [fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSLog(@"fileData length: %lu", [fileData length]);
    NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
    
    long long totalPayloadLength = [postBodyBeforeFile length] + [fileData length] + [postBodyAfterFile length];
    [request setValue:[[NSNumber numberWithLongLong:totalPayloadLength] stringValue] forHTTPHeaderField:@"Content-Length"];
    
    [postBodyBeforeFile appendData:fileData];
    [postBodyBeforeFile appendData:postBodyAfterFile];

    [request setHTTPBody:postBodyBeforeFile];
    
    FileUploadDelegate *delegate =[[FileUploadDelegate alloc] init];
    
    [NSURLConnection connectionWithRequest:request delegate:delegate];
    

}


#pragma mark 上传文件二(对应服务端的HandlerHeaderUploadFile)
-(void)BtnUploadFileMannerTwo:(id)sender{
    

    NSArray *patharray =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//测试的时候需要在Document目录下面放的文件

    NSString *uploadfilepath = [[patharray objectAtIndex:0] stringByAppendingPathComponent:@"download.rar"];
    
    NSData *fileData = [NSData dataWithContentsOfFile:uploadfilepath];
    NSString *fileName =[uploadfilepath lastPathComponent];
    
    NSURL *UrlServer =[NSURL URLWithString:uploadurl];
    
    NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:UrlServer];
    [request setHTTPMethod:@"POST"];
    NSString *contentType =[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
    
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"{\"name\":\"zhangsan\"}" forHTTPHeaderField:@"data"];//测试数据
    [request setValue:fileName forHTTPHeaderField:@"filename"];
    
    NSData* formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* postBodyBeforeFile = [NSMutableData data];
    [postBodyBeforeFile appendData:formBoundaryData];
    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Length: %lu\r\n\r\n", [fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSLog(@"fileData length: %lu", [fileData length]);
    NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
    
    long long totalPayloadLength = [postBodyBeforeFile length] + [fileData length] + [postBodyAfterFile length];
    [request setValue:[[NSNumber numberWithLongLong:totalPayloadLength] stringValue] forHTTPHeaderField:@"Content-Length"];
    
    [postBodyBeforeFile appendData:fileData];
    [postBodyBeforeFile appendData:postBodyAfterFile];
    [request setHTTPBody:postBodyBeforeFile];
    FileUploadDelegate *delegate =[[FileUploadDelegate alloc] init];
    [NSURLConnection connectionWithRequest:request delegate:delegate];
}



上传成功与失败的回调类FileUploadDelegate代码如下(下篇博文中下载类同这个一样):
enum FileTransferDirection{
    TRANSFER_UPLOAD = 1,
    TRANSFER_DOWNLOAD = 2,
};
typedef int FileTransferDirection;


@interface FileUploadDelegate : NSObject

-(void)cancelTransfer:(NSURLConnection *)connection;

@property(strong)NSMutableData *responseData;
@property(assign) NSInteger responseCode;
@property(nonatomic,assign)FileTransferDirection direction;
@property(nonatomic,strong)NSURLConnection *connection;
@property(nonatomic,copy)NSString *target;
@property(nonatomic,copy)NSString *mimeType;
@property(nonatomic,assign)long long bytesTransfered;
@property(nonatomic,assign)long long bytesExpected;
@property(strong)NSFileHandle *targetFileHandle;

@end

#import "FileUploadDelegate.h"

@implementation FileUploadDelegate

-(id)init{
    if((self =[super init])){
        self.responseData =[NSMutableData data];
        self.targetFileHandle = nil;
    }
    return  self;
}

-(void)removeTargetFile{
    NSFileManager *manager =[NSFileManager defaultManager];
    [manager removeItemAtPath:self.target error:nil];
}

-(void)cancelTransfer:(NSURLConnection *)connection{
    [connection cancel];
    [self removeTargetFile];
    
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection{
    NSLog(@"finishloading");
    
    NSString * uploadResponse = nil;
    NSString * downloadResponse = nil;
    
    if(self.direction == TRANSFER_DOWNLOAD){
        NSLog(@"下载完成");
        if(self.targetFileHandle){
            [self.targetFileHandle closeFile];
            self.targetFileHandle = nil;
            NSLog(@"File Transfer Download success");
        }else{
            downloadResponse =[[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
            NSLog(@"download response:%@",downloadResponse);
        }
    }
    if(self.direction == TRANSFER_UPLOAD){
        NSLog(@"上传文件完成");
        uploadResponse =[[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
        if((self.responseCode>=200) && (self.responseCode<300)){
            NSLog(@"");
        }else{
            NSLog(@"upload response:%@",uploadResponse);
        }
    }
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{
    NSLog(@"didresponse");
    
    NSError* __autoreleasing error = nil;
    self.targetFileHandle = nil;
    if([response isKindOfClass:[NSHTTPURLResponse class]]){
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse *)response;
        self.responseCode = [httpResponse statusCode] ;
        self.bytesExpected = [response expectedContentLength];
        NSDictionary * dic =[ httpResponse allHeaderFields];
        NSLog(@"Header:%@",dic);
        
    }else if([response.URL isFileURL]){
        NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:[response.URL path] error:nil];
        self.responseCode = 200;
        self.bytesExpected =[attr[NSFileSize] longLongValue];
    }else{
        self.responseCode = 200;
        self.bytesExpected = NSURLResponseUnknownLength;
    }
    
    if((self.direction == TRANSFER_DOWNLOAD)&&(self.responseCode >=200)&&(self.responseCode <300))
    {
        NSString *parentPath =[self.target stringByDeletingLastPathComponent];
        //创建父目录
        if([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO){
            if(error){
                NSLog(@"创建保存下载文件的路径错误:%@",[error localizedDescription]);
            }else{
                NSLog(@"创建保存文件路径错误");
            }
            return;
        }
        //创建目标文件
        if([[NSFileManager defaultManager] createFileAtPath:self.target contents:nil attributes:nil] == NO){
            NSLog(@"创建目标文件失败");
            return;
        }
        NSLog(@"target:%@",self.target);
        self.targetFileHandle =[NSFileHandle fileHandleForWritingAtPath:self.target];
        if(self.targetFileHandle == nil){
            NSLog(@"打开目标文件写数据出错");
        }
        
    }
    
}

- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{
    NSString *body =[[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
    NSLog(@"body:%@",body);
    NSLog(@"文件下载发生错误:%@",[error localizedDescription]);
    
    [self cancelTransfer:connection];
}
#pragma mark 处理文件下载的进度
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{
    NSLog(@"didreceivedata");
    self.bytesTransfered += data.length;
    if(self.targetFileHandle){
        [self.targetFileHandle writeData:data];
        
    }else{
        [self.responseData appendData:data];
    }
    if(self.direction == TRANSFER_UPLOAD){
        NSLog(@"上传了文件");
    }
    if(self.direction == TRANSFER_DOWNLOAD){
        NSLog(@"下载了文件,已经下载了:%lld,总共需要下载:%lld",self.bytesTransfered,self.bytesExpected);
    }
}
#pragma mark 处理文件上传的进度
- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite{
    
    
    NSLog(@"文件上传,本次传输:%ld %@,已经上传:%ld%@,总共上传:%ld%@",bytesWritten,@"字节",totalBytesWritten,@"字节",totalBytesExpectedToWrite,@"字节");
    
    self.bytesTransfered = totalBytesWritten;
}
@end



服务端代码下载

客户端代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值