上传大文件 NSInputStream

本文详细介绍了如何使用 iOS 的 NSInputStream 类实现大文件分块上传,通过实例代码解析了断点续传和错误处理策略,确保大文件在上传过程中的稳定性和效率。
/**
 *  @method + (NSString *)uploadVideoFilePath:(NSString *)filePath withFileName:(NSString *)fileName withFileExt:(NSString *)fileExt withErrorCode:(NSInteger *)errorCode
 *
 *  @abstract 上传文件
 *
 *  @param fileData   文件数据
 *  @param errorCode  [out]错误代码
 *
 *  @return 如果上传成功则返回资源路径
 */
+ (NSString *)uploadVideoFilePath:(NSString *)filePath
                     withFileName:(NSString *)fileName
                      withFileExt:(NSString *)fileExt
                    withErrorCode:(NSInteger *)errorCode
{
    NSMutableString * uploadFileURL = [[NSMutableString alloc] initWithCapacity:20];
    [uploadFileURL appendFormat:@"http://%@/upload_file",UPLOAD_HOST];
    [uploadFileURL appendFormat:@"?%@",[self getURLSuffixWithURL]];

    //创建Request对象
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:uploadFileURL]];
    [request setHTTPMethod:@"POST"];
    NSMutableData *body = [NSMutableData data];

    //设置表单项分隔符
    NSString *boundary = @"---------------------------20140601chrrsmusic1703";

    //设置内容类型
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

    //写入图片的内容
    NSString * fileFullName = [NSString stringWithFormat:@"%@.%@",fileName,fileExt];
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",fileName,fileFullName] dataUsingEncoding:NSUTF8StringEncoding]];
    NSString * contentTypeStr = [NSString stringWithFormat:@"Content-Type: video/%@\r\n\r\n",fileExt];
    [body appendData:[contentTypeStr dataUsingEncoding:NSUTF8StringEncoding]];
    //    NSString * appendDataStr = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]];
    //    DELOG(@"appendDataStr: \r\n%@",appendDataStr);

    // 视频数据
    NSInputStream * fileStream = [[NSInputStream alloc] initWithFileAtPath:filePath];
    [fileStream open];
    NSInteger maxLength = 128;
    uint8_t readBuffer [maxLength];
    BOOL endOfStreamReached = NO;
    while (! endOfStreamReached)
    {
        NSInteger bytesRead = [fileStream read:readBuffer maxLength:maxLength];
        if (bytesRead == 0)
        {//文件读取到最后
            endOfStreamReached = YES;
        }else if (bytesRead == -1)
        {//文件读取错误
            endOfStreamReached = YES;
        }else
        {
            [body appendBytes:readBuffer length:bytesRead];
        }
    }
    [fileStream close];

    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

    //写入尾部内容
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [request setHTTPBody:body];

    NSHTTPURLResponse *urlResponese = nil;
    NSError *error = [[NSError alloc]init];
    NSData* resultData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponese error:&error];
    if (!resultData) {
        *errorCode = -1;
        return nil;
    }
    NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingMutableLeaves error:nil];
    NSInteger statusCode = [[NSString ensureStringFor:[jsonData objectForKey:@"state"]] integerValue];
    *errorCode = statusCode;
    if (statusCode == 402) {
        // 发出需要登录的通知
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_NEED_LOGINTOKEN
                                                                object:nil];
        });
    }

    if (statusCode != 0) {
        *errorCode = statusCode;
        return nil;
    }else{
        NSDictionary * data = [jsonData objectForKey:@"data"];
        if (![data isKindOfClass:[NSDictionary class]]) {
            return nil;
        }else{
            NSString * fileURL = [NSString ensureStringFor:[data objectForKey:@"uri"]];
            return fileURL;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值