前言
最近在整理梳理斷點續(xù)傳的功能,查看了許多關(guān)于大文件存儲實現(xiàn)的方式。梳理一下它們的特點。
實現(xiàn)文件存儲的三種方式
NSMutableDdata方式拼接
NSFileHandle
NSOutputStream
NSMutableDdata
當下載大文件時候,我們是通過代理回調(diào),一點一點獲取數(shù)據(jù)。如果使用NSMutableDdata拼接數(shù)據(jù),會使得內(nèi)存暴增。所以不能使用NSMutableDdata拼接數(shù)據(jù)保存
#pragma mark - <NSURLSessionDataDelegate> 實現(xiàn)方法
@property (nonatomic, strong)NSMutableData *fileData;
/**
* 接收到具體數(shù)據(jù):把數(shù)據(jù)寫入沙盒文件中
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 每次下載的data存儲到fileData中,會導致內(nèi)存暴漲 [self.fileData appendData:data];
}
NSFilehandle
該類就是專門用于操作文件(handle),下載大文件的操作步驟。
//1.獲取每次從服務(wù)器獲取的data
//2.沙盒文件路徑
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"yyy.mp4"];
//3.沒有文件創(chuàng)建一個文件
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:path]) {
//創(chuàng)建一個空的文件
[manager createFileAtPath:path contents:nil attributes:nil];
}
// 4、創(chuàng)建文件句柄,設(shè)置句柄寫數(shù)據(jù)的位置(追加)
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
[fileHandle seekToEndOfFile];
//5.向沙盒指定文件寫入數(shù)據(jù)
[fileHandle writeData:data];
//6.當下載完成之后,文件文件句柄
[fileHandle closeFile];
fileHandle = nil;
NSOutputStream
NSStream是一個抽象類和NSOperation一樣是用來約束子類的,NSOutputStream就是NSStream的一個子類.
NSOutputStream這個就是輸出流就像一個集合,往里面加數(shù)據(jù)就好了,其實網(wǎng)絡(luò)在傳輸數(shù)據(jù)的話都是以一個二進制流的方式進行傳遞的。
//1.獲取每次從服務(wù)器獲取的data
//2.沙盒文件路徑
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"yyy.mp4"];
//3.創(chuàng)建并打開數(shù)據(jù)流
/*
第一個參數(shù):二進制的流數(shù)據(jù)要寫入到哪里(沒有就創(chuàng)建,有就直接寫入,不用自己創(chuàng)建文件)
第二個參數(shù):采用什么樣的方式寫入流數(shù)據(jù),如果YES則表示追加,如果是NO則表示覆蓋
*/
NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];
[outputStream open];
//4.使用輸出流寫數(shù)據(jù)
/*
第一個參數(shù):二進制數(shù)據(jù)流
第二個參數(shù):要寫入的數(shù)據(jù)的大小
*/
[outputStream write:data.bytes maxLength:data.length];
//關(guān)閉輸出流
[outputStream close];
outputStream = nil;
總結(jié)
不建議使用NSMutableData存儲大文件數(shù)據(jù),會使內(nèi)存暴漲。
-
NSOutputStream與NSFileHandle區(qū)別:
- NSOutputStream不用判斷是否有這個路徑文件,如果沒有就自動創(chuàng)建,有的話直接寫入數(shù)據(jù)。
- NSOutputStream寫進的是二進制流:data.bytes,NSFileHandle寫進的是二進制數(shù)據(jù):data