@@ -51,10 +51,15 @@ @interface QCloudCOSXMLUploadObjectRequest ()<QCloudHttpRetryHandlerProtocol>
5151{
5252 NSRecursiveLock * _recursiveLock;
5353 NSRecursiveLock * _progressLock;
54+ NSUInteger uploadedSize;
55+ // 标记下标,从0开始
56+ NSUInteger startPartNumber;
57+ BOOL isChange;
5458}
5559@property (nonatomic , assign ) int64_t totalBytesSent;
5660@property (nonatomic , assign ) NSUInteger dataContentLength;
5761@property (nonatomic , strong ) dispatch_source_t queueSource;
62+ // 存储所有的分片
5863@property (nonatomic , strong ) NSMutableArray <QCloudMultipartInfo*>* uploadParts;
5964@property (nonatomic , strong ) NSString * uploadId;
6065@property (nonatomic , strong ) NSPointerArray * requestCacheArray;
@@ -91,6 +96,7 @@ - (instancetype) init
9196 _requstMetricArray = [NSMutableArray array ];;
9297 _enableMD5Verification = YES ;
9398 _retryHandler = [QCloudHTTPRetryHanlder defaultRetryHandler ];
99+ startPartNumber = -1 ;
94100 return self;
95101}
96102- (NSDictionary *)modelCustomWillTransformFromDictionary : (NSDictionary *)dictionary {
@@ -134,27 +140,77 @@ - (void) continueMultiUpload:(QCloudListPartsResult*)existParts
134140 [existMap setObject: part forKey: part.partNumber];
135141 }
136142 QCloudLogDebug (@" SERVER EXIST PARTS %@ " , [existParts qcloud_modelToJSONString ]);
137-
143+
138144 NSMutableArray * restParts = [NSMutableArray new ];
139145 for (QCloudFileOffsetBody* offsetBody in allParts) {
140146 NSString * key = [@(offsetBody.index+1 ) stringValue ];
141147 QCloudMultipartUploadPart* part = [existMap objectForKey: key];
148+
142149 if (!part) {
143150 [restParts addObject: offsetBody];
144151 } else {
152+ if (part.size != offsetBody.sliceLength ) {
153+ isChange = YES ;
154+ break ;
155+ }
145156 QCloudMultipartInfo* info = [QCloudMultipartInfo new ];
146157 info.eTag = part.eTag ;
147158 info.partNumber = part.partNumber ;
148159 [_uploadParts addObject: info];
149160 }
150161 }
151- if (restParts.count == 0 ) {
152- [self finishUpload: self .uploadId];
153- } else {
154- [self uploadOffsetBodys: restParts];
162+
163+ if (!isChange) {
164+ if (restParts.count == 0 ) {
165+ [self finishUpload: self .uploadId];
166+ }else {
167+ [self uploadOffsetBodys: restParts];
168+ }
169+ }else {
170+ // 重新分片
171+ [self getContinueInfo: existParts.parts];
172+ if (uploadedSize == self.dataContentLength ) {
173+ [self finishUpload: self .uploadId];
174+ } else {
175+ // 开始分片
176+ [self uploadOffsetBodys: [self getFileLocalUploadParts ]];
177+ }
178+ }
179+ }
180+
181+ -(void )getContinueInfo : (NSArray *)existParts {
182+ _uploadParts = [NSMutableArray new ];
183+ int i=1 ;
184+ QCloudMultipartUploadPart *part = existParts[0 ];
185+ QCloudMultipartInfo* info = [QCloudMultipartInfo new ];
186+ info.eTag = part.eTag ;
187+ info.partNumber = part.partNumber ;
188+ if ([info.partNumber integerValue ]!=1 ){
189+ return ;
155190 }
191+
192+ for (i = 0 ; i<existParts.count ; i++) {
193+ QCloudMultipartUploadPart *part1 = existParts[i];
194+ QCloudMultipartInfo* info1 = [QCloudMultipartInfo new ];
195+ info1.eTag = part1.eTag ;
196+ info1.partNumber = part1.partNumber ;
197+ uploadedSize+=part1.size ;
198+ [_uploadParts addObject: info1];
199+ if (i == existParts.count -1 ) {
200+ break ;
201+ }
202+ QCloudMultipartUploadPart *part2 = existParts[i+1 ];
203+ if (([part1.partNumber integerValue ]+1 )!= [part2.partNumber integerValue ]) {
204+ break ;
205+ }
206+
207+ }
208+ startPartNumber = _uploadParts.count ;
209+
210+ QCloudLogDebug (@" resume startPartNumber = offset = %ld %ld " ,startPartNumber,uploadedSize);
156211}
157212
213+
158214- (void ) resumeUpload
159215{
160216 QCloudListMultipartRequest* request = [QCloudListMultipartRequest new ];
@@ -179,6 +235,8 @@ - (void) resumeUpload
179235- (void ) fakeStart {
180236 [self .benchMarkMan benginWithKey: kTaskTookTime ];
181237 if (self.uploadId ) {
238+ startPartNumber = 0 ;
239+ uploadedSize = 0 ;
182240 [self resumeUpload ];
183241 return ;
184242 }
@@ -190,6 +248,9 @@ - (void) fakeStart {
190248 NSURL * url = (NSURL *)self.body ;
191249 self.dataContentLength = QCloudFileSize (url.path );
192250 if (self.dataContentLength > kQCloudCOSXMLUploadLengthLimit ) {
251+ // 开始分片上传的时候,上传的起始位置是0
252+ uploadedSize = 0 ;
253+ startPartNumber = 0 ;
193254 [self startMultiUpload ];
194255 } else {
195256 [self startSimpleUpload ];
@@ -305,12 +366,14 @@ - (void) startMultiUpload {
305366{
306367 NSMutableArray * allParts = [NSMutableArray new ];
307368 NSURL * url = (NSURL *)self.body ;
308- int64_t restContentLength = self.dataContentLength ;
309- int64_t offset = 0 ;
310- for (int i = 0 ; ;i++ ) {
369+ int64_t restContentLength = self.dataContentLength -uploadedSize;
370+ // 便宜的起始位置
371+ int64_t offset = uploadedSize;
372+ for (int i = startPartNumber; ;i++ ) {
311373 int64_t slice = 0 ;
312- if (restContentLength >= kQCloudCOSXMLUploadSliceLength ) {
313- slice = kQCloudCOSXMLUploadSliceLength ;
374+ NSUInteger uploadSliceLength = self.sliceSize >10 ?self.sliceSize :kQCloudCOSXMLUploadSliceLength ;
375+ if (restContentLength >= uploadSliceLength) {
376+ slice = uploadSliceLength;
314377 } else {
315378 slice = restContentLength;
316379 }
0 commit comments