断点续传和分块上传

#pragma mark   异步上传

- (void)uploadObjectAsync:(NSString *)FileURL objectKey:(NSString *)objectKey{

OSSPutObjectRequest * put = [OSSPutObjectRequest new];

NSLog(@"objectKey is %@",objectKey);

// required fields

put.bucketName = bucketName;

put.objectKey = objectKey;

put.uploadingFileURL = [NSURL fileURLWithPath:FileURL];

// optional fields

put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float  gress = (double)totalByteSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上传中");

}

});

};

OSSTask * putTask = [client putObject:put];

[putTask continueWithBlock:^id(OSSTask *task) {

NSLog(@" putTask  :%@",putTask.result);

NSLog(@"objectKey: %@", put.objectKey);

uploadputkey = put.objectKey;

if (!task.error) {

NSLog(@"upload object success!");

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

} else {

NSLog(@"upload object failed, error: %@" , task.error);

}

return nil;

}];

}

#pragma mark  同步上传

- (void)uploadObjectSync:(NSString *)FileURL objectKey:(NSString *)objectKey {

OSSPutObjectRequest * put = [OSSPutObjectRequest new];

// required fields

put.bucketName = bucketName;

put.objectKey = objectKey;

put.uploadingFileURL = [NSURL fileURLWithPath:FileURL];

// optional fields

put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"uploadProgress is  %lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float  gress = totalByteSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123");

}

});

};

OSSTask * putTask = [client putObject:put];

[putTask waitUntilFinished]; // 阻塞直到上传完成

NSLog(@" putTask  :%@",putTask.result);

if (!putTask.error) {

NSLog(@"upload object success!");

NSLog(@" putTask  :%@",putTask.result);

NSLog(@"objectKey: %@", put.objectKey);

uploadputkey = put.objectKey;

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

} else {

NSLog(@"upload object failed, error: %@" , putTask.error);

}

}

#pragma mark  追加上传

- (void)appendObject {

OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];

// 必填字段

append.bucketName = @"android-test";

append.objectKey = @"file1m";

append.appendPosition = 0; // 指定从何处进行追加

NSString * docDir = [self getDocumentDirectory];

append.uploadingFileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"file1m"]];

// 可选字段

append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

};

// append.contentType = @"";

// append.contentMd5 = @"";

// append.contentEncoding = @"";

// append.contentDisposition = @"";

OSSTask * appendTask = [client appendObject:append];

NSLog(@" putTask  :%@",appendTask.result);

[appendTask continueWithBlock:^id(OSSTask *task) {

NSLog(@"objectKey: %@", append.objectKey);

if (!task.error) {

NSLog(@"append object success!");

OSSAppendObjectResult * result = task.result;

NSString * etag = result.eTag;

long nextPosition = result.xOssNextAppendPosition;

NSLog(@"etag: %@, nextPosition: %ld", etag, nextPosition);

} else {

NSLog(@"append object failed, error: %@" , task.error);

}

return nil;

}];

}

#pragma mark  异步下载

- (void)downloadObjectAsync {

OSSGetObjectRequest * request = [OSSGetObjectRequest new];

// required

request.bucketName = @"android-test";

request.objectKey = @"file1m";

//optional

request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {

NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);

};

OSSTask * getTask = [client getObject:request];

[getTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"download object success!");

OSSGetObjectResult * getResult = task.result;

NSLog(@"download dota length: %lu", [getResult.downloadedData length]);

} else {

NSLog(@"download object failed, error: %@" ,task.error);

}

return nil;

}];

}

#pragma mark   同步下载

- (void)downloadObjectSync {

OSSGetObjectRequest * request = [OSSGetObjectRequest new];

// required

request.bucketName = @"android-test";

request.objectKey = @"file1m";

//optional

request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {

NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);

};

// NSString * docDir = [self getDocumentDirectory];

// request.downloadToFileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"downloadfile"]];

OSSTask * getTask = [client getObject:request];

[getTask waitUntilFinished];

if (!getTask.error) {

OSSGetObjectResult * result = getTask.result;

NSLog(@"download data length: %lu", [result.downloadedData length]);

} else {

NSLog(@"download data error: %@", getTask.error);

}

}

#pragma mark   获取meta

- (void)headObject {

OSSHeadObjectRequest * head = [OSSHeadObjectRequest new];

head.bucketName = @"android-test";

head.objectKey = @"file1m";

OSSTask * headTask = [client headObject:head];

[headTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

OSSHeadObjectResult * headResult = task.result;

NSLog(@"all response header: %@", headResult.httpResponseHeaderFields);

// some object properties include the ‘x-oss-meta-*‘s

NSLog(@"head object result: %@", headResult.objectMeta);

} else {

NSLog(@"head object error: %@", task.error);

}

return nil;

}];

}

#pragma mark   删除Object

- (void)deleteObject {

OSSDeleteObjectRequest * delete = [OSSDeleteObjectRequest new];

delete.bucketName = @"android-test";

delete.objectKey = @"file1m";

OSSTask * deleteTask = [client deleteObject:delete];

[deleteTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"delete success !");

} else {

NSLog(@"delete erorr, error: %@", task.error);

}

return nil;

}];

}

#pragma mark   复制Object

- (void)copyObjectAsync {

OSSCopyObjectRequest * copy = [OSSCopyObjectRequest new];

copy.bucketName = @"android-test"; // 复制到哪个bucket

copy.objectKey = @"file_copy_to"; // 复制为哪个object

copy.sourceCopyFrom = [NSString stringWithFormat:@"/%@/%@", @"android-test", @"file1m"]; // 从哪里复制

OSSTask * copyTask = [client copyObject:copy];

[copyTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"copy success!");

} else {

NSLog(@"copy error, error: %@", task.error);

}

return nil;

}];

}

#pragma mark  签名URL授予第三方访问

- (void)signAccessObjectURL {

NSString * constrainURL = nil;

NSString * publicURL = nil;

// sign constrain url

OSSTask * task = [client presignConstrainURLWithBucketName:bucketName

withObjectKey:uploadputkey

withExpirationInterval:60 * 30];

//    if (!task.error) {

//        constrainURL = task.result;

//        NSLog(@"constrainURL is %@",constrainURL);

//        postPublicURL = publicURL;

//        [self createTranscodeJobFlow];

//    } else {

//        NSLog(@"error: %@", task.error);

//    }

// sign public url

task = [client presignPublicURLWithBucketName:bucketName

withObjectKey:uploadputkey];

if (!task.error) {

publicURL = task.result;

NSLog(@"publicURL is %@",publicURL);

postPublicURL = publicURL;

[self createTranscodeJobFlow];

} else {

NSLog(@"sign url error: %@", task.error);

}

}

#pragma mark   分块上传

- (void)multipartUpload:(NSString *)FileURL objectKey:(NSString *)objectKey{

__block NSString * uploadId = nil;

__block NSMutableArray * partInfos = [NSMutableArray new];

NSString * uploadToBucket = bucketName;

NSString * uploadObjectkey = objectKey;

OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];

init.bucketName = uploadToBucket;

init.objectKey = uploadObjectkey;

init.contentType = @"video/x-m4v";

init.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil];

OSSTask * initTask = [client multipartUploadInit:init];

[initTask waitUntilFinished];

if (!initTask.error) {

OSSInitMultipartUploadResult * result = initTask.result;

MUuploadID = result.uploadId;

uploadputkey =objectKey;

NSLog(@"init multipart upload success: %@", result.uploadId);

} else {

NSLog(@"multipart upload failed, error: %@", initTask.error);

return;

}

NSDictionary * pathsize =  [self getVideoInfoWithSourcePath:FileURL];

NSInteger videoSize = [pathsize[@"size"]integerValue];

//要上传的文件

chuckCount = 100; // 10块 好区分图谱

//分片上传数量

uint64_t offset = videoSize/chuckCount;

for (int i = 1; i <= chuckCount; i++) {

@autoreleasepool {

OSSUploadPartRequest * uploadPart = [OSSUploadPartRequest new];

uploadPart.bucketName = uploadToBucket;

uploadPart.objectkey = uploadObjectkey;

uploadPart.uploadId = uploadId;

uploadPart.partNumber = i; // part number start from 1

NSString * docDir = FileURL;

uploadPart.uploadPartFileURL = [NSURL URLWithString:docDir];

NSFileHandle* readHandle = [NSFileHandle fileHandleForReadingAtPath:FileURL];

[readHandle seekToFileOffset:offset * (i -1)];

NSData* data = [readHandle readDataOfLength:offset];

uploadPart.uploadPartData = data;

//            uploadPart.uploadPartProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {

//                 NSLog(@"%lld %lld %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);

//                dispatch_async(dispatch_get_main_queue(), ^{

//                    float  gress = (double)totalBytesSent/totalBytesExpectedToSend;

//                    if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

//                        [self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

//                        NSLog(@"gress123上传中");

//                    }

//                });

//            };

OSSTask * uploadPartTask = [client uploadPart:uploadPart];

[uploadPartTask waitUntilFinished];

if (!uploadPartTask.error) {

OSSUploadPartResult * result = uploadPartTask.result;

uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteString error:nil] fileSize];

[partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTag size:fileSize]];

[self listParts:MUuploadID PartNumber:uploadPart.partNumber];

} else {

NSLog(@"upload part error: %@", uploadPartTask.error);

return;

}

}

}

//    OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];

//    complete.bucketName = uploadToBucket;

//    complete.objectKey = uploadObjectkey;

//    complete.uploadId = uploadId;

//    complete.partInfos = partInfos;

//

//    OSSTask * completeTask = [client completeMultipartUpload:complete];

//

//    [completeTask waitUntilFinished];

//

//    if (!completeTask.error) {

//        NSLog(@"multipart upload success!");

//

//    } else {

//        NSLog(@"multipart upload failed, error: %@", completeTask.error);

//        return;

//    }

}

#pragma mark  罗列分块

- (void)listParts:(NSString *)uploadId PartNumber:(int)partNumber{

OSSListPartsRequest * listParts = [OSSListPartsRequest new];

listParts.bucketName = bucketName;

listParts.objectKey = uploadputkey;

listParts.uploadId = uploadId;

OSSTask * listPartTask = [client listParts:listParts];

[listPartTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"list part result success!");

OSSListPartsResult * listPartResult = task.result;

dispatch_async(dispatch_get_main_queue(), ^{

float  gress = (double)partNumber/chuckCount;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上传中");

}

if (gress == 1.0) {

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

}

});

NSLog(@"listPartResult is%@",listPartResult);

for (NSDictionary * partInfo in listPartResult.parts) {

NSLog(@"partInfoeachpart: %@", partInfo);

}

} else {

NSLog(@"list part result error: %@", task.error);

}

return nil;

}];

}

#pragma mark ----// 断点续传 ----

- (void)resumableUpload:(NSString *)FileURL objectKey:(NSString *)objectKey{

__block NSString * recordKey;

//    NSString * docDir = [self getDocumentDirectory];

NSString * filePath =FileURL;

//    NSString * bucketName = bucketName;

//    objectKey = @"uploadKey";

[[[[[[OSSTask taskWithResult:nil] continueWithBlock:^id(OSSTask *task) {

// 为该文件构造一个唯一的记录键

NSURL * fileURL = [NSURL fileURLWithPath:filePath];

NSDate * lastModified;

NSError * error;

[fileURL getResourceValue:&lastModified forKey:NSURLContentModificationDateKey error:&error];

if (error) {

return [OSSTask taskWithError:error];

}

recordKey = [NSString stringWithFormat:@"%@-%@-%@-%@", bucketName, objectKey, [OSSUtil getRelativePath:filePath], lastModified];

// 通过记录键查看本地是否保存有未完成的UploadId

NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];

return [OSSTask taskWithResult:[userDefault objectForKey:recordKey]];

}] continueWithSuccessBlock:^id(OSSTask *task) {

if (!task.result) {

// 如果本地尚无记录,调用初始化UploadId接口获取

OSSInitMultipartUploadRequest * initMultipart = [OSSInitMultipartUploadRequest new];

initMultipart.bucketName = bucketName;

initMultipart.objectKey = objectKey;

initMultipart.contentType = @"video/x-m4v";

return [client multipartUploadInit:initMultipart];

}

OSSLogVerbose(@"An resumable task for uploadid: %@", task.result);

return task;

}] continueWithSuccessBlock:^id(OSSTask *task) {

NSString * uploadId = nil;

if (task.error) {

return task;

}

if ([task.result isKindOfClass:[OSSInitMultipartUploadResult class]]) {

uploadId = ((OSSInitMultipartUploadResult *)task.result).uploadId;

} else {

uploadId = task.result;

}

if (!uploadId) {

return [OSSTask taskWithError:[NSError errorWithDomain:OSSClientErrorDomain

code:OSSClientErrorCodeNilUploadid

userInfo:@{OSSErrorMessageTOKEN: @"Can‘t get an upload id"}]];

}

// 将“记录键:UploadId”持久化到本地存储

NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];

[userDefault setObject:uploadId forKey:recordKey];

[userDefault synchronize];

return [OSSTask taskWithResult:uploadId];

}] continueWithSuccessBlock:^id(OSSTask *task) {

// 持有UploadId上传文件

_resumableUpload = [OSSResumableUploadRequest new];

_resumableUpload.bucketName = bucketName;

_resumableUpload.objectKey = objectKey;

_resumableUpload.uploadId = task.result;

_resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:filePath];

_resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld %lld %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float  gress = (double)totalBytesSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上传中");

}

});

};

return [client resumableUpload:_resumableUpload];

}] continueWithBlock:^id(OSSTask *task) {

if (task.error) {

if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {

// 如果续传失败且无法恢复,需要删除本地记录的UploadId,然后重启任务

[[NSUserDefaults standardUserDefaults] removeObjectForKey:recordKey];

}

} else {

NSLog(@"%@",task.result);

NSLog(@"%@",self->_resumableUpload.objectKey);

NSLog(@"upload completed!");

uploadputkey = _resumableUpload.objectKey;

// 上传成功,删除本地保存的UploadId

[[NSUserDefaults standardUserDefaults] removeObjectForKey:recordKey];

NSLog(@"upload object success!");

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

}

return nil;

}];

}

-(void)cannelUpdate{

[_resumableUpload cancel];

//    _resumableUpload = nil;

NSLog(@"取消网络操作");

//    [OSSTask cancelledTask];

}

#pragma mark --检查数据大小---

- (NSDictionary *)getVideoInfoWithSourcePath:(NSString *)path{

NSLog(@"%@",path);

AVURLAsset * asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];

CMTime   time = [asset duration];

int seconds = ceil(time.value/time.timescale);

NSInteger   fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;

return @{@"size" : @(fileSize),

@"duration" : @(seconds)};

}

原文地址:https://www.cnblogs.com/tangyuanby2/p/8358925.html

时间: 2024-11-20 08:27:37

断点续传和分块上传的相关文章

Aliyun OSS SDK 异步分块上传导致应用异常退出

问题描述: 使用Aliyun OSS SDK的BeginUploadPart/EndUploadPart执行异步分块上传操作,程序出现错误并异常退出! 原因分析: Using .NET Framework 2.0, unhandled exceptions, no matter where they come from, will cause termination of the app. (详见:Exceptions in Managed Threads:https://msdn.micros

文件分块上传客户端实现

首先对文件按内容分块(有块大小的约束),然后对于每个chunk构造单独的一个UDP 数据报进行传输,在应用层的开始是自定义的包头,有块号,块长度,块指纹等元数据信息,这些信息便于接收端能够按序正确接收. /*--vonzhou ---this project is to upload file after chunking using rabin fingerprint, here use UDP so that every packet nodelay. but we need to ensu

net core分块上传文件

net core分块上传文件 写完asp.net多文件上传(http://www.cnblogs.com/bestckk/p/5987383.html)后,感觉这种上传还是有很多缺陷,于是...(省略一万字,不废话).这里我没用传统的asp.net,而选择了开源的asp.net core,原因很简单,.net core是.net新的开始,更是.net和.net开发者的未来,希望.net发展越来越好(大家的工资越来越高(●ˇ?ˇ●)). 1.前端的实现: 1).html: 1 <html> 2

【纯干货】4年前想解决的事情,今天才实验成功:浏览器原生分块上传文件

第一份软件开发工作的第一个星期(不算做试用期的一个星期,无薪水试用).因为不是软件专业,也没有经过培训和相关工作经验.老板不放心,但还是让我试一试.做的第一件事情就是上传文件,实时看进度,并且上传后预览.预览的文件类型有word,ppt,excel,flash,视频按帧获取预览图.office文件是在服务器端转成html后显示出来. 做的还满意,就留下来了,后来就在那个公司待了两年. 没解决的事情: 上传大文件,分块上传,浏览器原生不支持,需要借助第三方插件.最根本的原因就是浏览器端的js考虑的

HTML5+AJAX原生分块上传文件的关键参数设置

processData:false 这是jquery.ajax的一个参数.默认值为true,表示会将非字符串对象自动变成k1=v1&k2=v2的形式,例如一个数组参数{d:[1,2]},到服务端后会变成d[]=1&d[]=2的形式. 要将其设置为false后,才能上传ArrayBuffer对象,服务端直接从Request.InputStream获取原始字节流. w3school解释: processData 类型:Boolean 默认值: true.默认情况下,通过data选项传递进来的数

使用JS实现可断点续传的文件上传方案

刚开始学习前端开发就碰到文件上传问题,还要求可断点续传.查了很多资料,发现H5的file API刚好可以满足我们的需求,也遇到了一些问题,于是记录下来为有同样需求的朋友提供一些帮助. 一.首先,为了引入文件对象,我们需要在H5页面上放置一个file类型的输入标签. 1 <input type="file" id="file" onchange="fileInfo()"> 当我们选择文件之后显示文件相关信息: 1 function fi

WebApi 文件上传,断点上传,分块上传,断点下载,查询 (图片的直接预览,视频边加载边播放)

using Manjinba.Communication.Common.Caching;using Manjinba.Communication.Common.Logging;using Manjinba.Communication.Common.Utils;using Manjinba.Communication.IRepository;using Manjinba.Communication.IService;using Manjinba.Communication.Model;using

asp.net core分块上传文件

写完asp.net多文件上传(http://www.cnblogs.com/bestckk/p/5987383.html)后,感觉这种上传还是有很多缺陷,于是...(省略一万字,不废话).这里我没用传统的asp.net,而选择了开源的asp.net core,原因很简单,.net core是.net新的开始,更是.net和.net开发者的未来,希望.net发展越来越好(大家的工资越来越高(●ˇ?ˇ●)). 1.前端的实现: 1).html: 1 <html> 2 <head> 3

vc++ socket http协议post方法上传 分块上传

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 最近项目需要,通过C++客户端向Web服务器用http协议上传文件,网上介绍这方面的好像很少,所以做了个基础的发上来供学习交流: 本人学c++没几天,代码可能比较烂,大家凑合看吧.. 示例代码: 1.C++ Clinet [cpp] view plaincopy #include "stdio.h" #include &q