這篇文章主要介紹iOS如何實現(xiàn)大文件的分片上傳和斷點上傳,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
10年積累的做網(wǎng)站、網(wǎng)站設(shè)計經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有建陽免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。1、首先獲取文件(音視頻、圖片)
分兩種情況,一種是在相冊庫里直接獲取,一種是調(diào)用相機。如果是通過UIImagePickerView來獲?。毠?jié)不詳述,網(wǎng)上一大堆),我們會發(fā)現(xiàn)當(dāng)你選定一個視頻的時候,會出現(xiàn)圖1的壓縮頁面,最后我們的app獲取的視頻就是這個經(jīng)過壓縮后的視頻(不是視頻庫里的原始視頻,這里有個注意點,操作完該壓縮視頻后記得釋放,系統(tǒng)不會幫你釋放的,需要你手動來操作,下面會說到),然后通過UIImagePickerView的協(xié)議方法中的- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info獲取視頻的Info
fileInfo = { UIImagePickerControllerMediaType = "public.movie"; UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/2AAE9E44-0E6D-4499-9AC3-93D44D8342EA/tmp/trim.F36EC46C-4219-43C8-96A7-FA7141AB64D2.MOV"; UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=DEDA9406-3223-4F87-ABB2-98FB5F5EB9C4&ext=MOV"; }
UIImagePickerControllerMediaType是選取文件的類型,如KUTTypeImage,KUTTypeMovie。這里注意一下movie和video的區(qū)別,一個是有聲音的視頻文件,一個是沒有聲音的視頻文件,當(dāng)然還有Audio是只有聲音沒有視頻。UIImagePickerControllerMediaURL是視頻的URL(如果是相機拍攝的,那么這個就是原始拍攝得到的視頻;如果是在相冊庫里選擇的,那就是壓縮之后生成的視頻),注意這個URL不指向相冊庫,通過這個URL你可以操作這個視頻如刪除,拷貝等,可以獲取壓縮后的視頻的大小。UIImagePickerControllerReferenceURL是一個指向相冊的URL,官方的解釋是an NSURL that references an asset in the AssetsLibrary framework,通過這個URL,你可以獲取視頻的所有信息,包括文件名,縮略圖,時長等(通過ALAssetsLibrary里的assetsLibraryassetForURL:referenceURLresultBlock:)。
如果是相機拍攝的,注意兩個保存方法:圖片保存到相冊
assetsLibrarywriteImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation([infovalueForKey:UIImagePickerControllerOriginalImage],(CGFloat)1.0)metadata:nilcompletionBlock: failureBlock:
高保真壓縮圖片的方法NSData * UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality)
視頻保存到相冊:assetsLibrarywriteVideoAtPathToSavedPhotosAlbum:MediaURL completionBlock:failureBlock:
到這里,我們就獲取了所有需要的文件以及文件信息。下面要做的就是將文件分片。
2、將獲取到的文件分片
首先,我將獲取到的文件保存在這這樣一個類中
@interface CNFile :NSObject @property(nonatomic,copy)NSString* fileType;//image or movie @property(nonatomic,copy)NSString* filePath;//文件在app中路徑 @property(nonatomic,copy)NSString* fileName;//文件名 @property(nonatomic,assign)NSIntegerfileSize;//文件大小 @property (nonatomic,assign)NSIntegertrunks;//總片數(shù) @property(nonatomic,copy)NSString* fileInfo; @property(nonatomic,strong)UIImage* fileImage;//文件縮略圖 @property(nonatomic,strong) NSMutableArray* fileArr;//標(biāo)記每片的上傳狀態(tài) @end
這樣我們就可以對每一個CNFile對象進行操作了。
-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{
總片數(shù)的獲取方法:
intoffset =1024*1024;(每一片的大小是1M) NSIntegerchunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) +1)); NSLog(@"chunks = %ld",(long)chunks);
將文件分片,讀取每一片的數(shù)據(jù):
NSData* data; NSFileHandle*readHandle = [NSFileHandlefileHandleForReadingAtPath:file.filePath]; [readHandleseekToFileOffset:offset * chunk]; data = [readHandlereadDataOfLength:offset]; }
這樣我們就獲取了每一片要上傳的數(shù)據(jù),然后詢問服務(wù)器,該片是否已經(jīng)存在
(方法-(void)ifHaveData:(NSData*)data WithChunk:(NSInteger)chunk file:(CNFile*)file)
,如果存在,令chunk+1,重復(fù)上面的方法讀取下一片,直到服務(wù)器不存在該片,那么上傳該片數(shù)據(jù)。在這個方法中注意設(shè)置該chunk的上傳狀態(tài)(wait loading finish),這將關(guān)系到本地判斷該文件是否已全部上傳完成。
下一步就是上傳的過程:
-(void)uploadData:(NSData*) data WithChunk:(NSInteger) chunk file:(CNFile*)file;
在服務(wù)器返回該片上傳成功后,我們要做的事有很多:
1)先將已經(jīng)成功上傳的本片的flag置finish
[file.fileArrreplaceObjectAtIndex:chunk withObject:@“finish"];
2)查看是否所有片的flag都已經(jīng)置finish,如果都已經(jīng)finishi,說明該文件上傳完成,那么刪除該文件,上傳下一個文件或者結(jié)束。
for(NSIntegerj =0; j if(j == chunks || ((j == chunks -1)&&([file.fileArr[j]isEqualToString:@"finish"]))) [medeleteFile:file.filePath]; [mereadNextFile]; }
3)如果沒有都finish,那么看本地下一chunk對用的flag是否是wait
NSLog(@"查看第%ld片的狀態(tài)",chunk+1); for(NSIntegeri = chunk+1;i < chunks;i++) { NSString* flag = [file.fileArrobjectAtIndex:i]; if([flagisEqualToString:@"wait"]) { [mereadDataWithChunk:ifileName:fileNamefile:file]; break; } }
在第2、3步之間可以有一個 2.5)判斷是否暫停上傳
if(me.isPause ==YES) { //將目前讀到了第幾個文件的第幾片保存到本地 [selfsaveProgressWithChunk:chunk file:file]; return; }
這個操作實際上和上傳過程中斷網(wǎng)是一樣的,為了斷點續(xù)傳,在斷網(wǎng)或者暫停的時候,我們要將目前的進度保存起來,以便下次上傳時略過前面已置finish的片。
然后還有一個問題,如果我們就這樣線性的一片一片上傳,實際上失去了分片上傳的意義,應(yīng)該結(jié)合多線程,使分片上傳過程并發(fā)執(zhí)行,同時上傳多片,這樣就提高了上傳效率,并充分利用了網(wǎng)絡(luò)帶寬。
dispatch_async(dispatch_queue_t queue, ^{ [mereadDataWithChunk: chunk]; })
最后注意一下,每上傳完一個視頻,去設(shè)置里看看你的app占用的存儲空間有沒有增大哦,如果你沒有處理那個生成的壓縮視頻,你會發(fā)現(xiàn)你的app的空間占用量是很大的。
以上是“iOS如何實現(xiàn)大文件的分片上傳和斷點上傳”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。