[英]Downloading large base64encoded data using NsurlConnection
我正在嘗試使用POST請求從服務器下載大文件。 該文件作為base64Encoded數據接收。 文件大小超過400Mb。 我使用的第一種方法是將在didReceiveData中接收到的數據附加到然后在connectionDidFinishLoading中用於解碼數據並將數據寫入文檔目錄中的文件。 此方法適用於小文件。 但是由於文件大小很大(400MB)而崩潰。 然后,當接收到數據時,我使用NSFileHandle的方法將文件分塊寫入。 我使用了3MB的塊來寫入數據。 對於小於3MB的文件,直接從base64解碼接收到的數據,並成功創建文件。 但是,當文件大小大於3MB時,我嘗試使用“ initWithBase64EncodedData:Options ”從base64解碼塊數據,得到的數據為零。 想知道我在代碼中做錯了什么。
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
receivedData = [[NSMutableData alloc] init];
NSString* folderPath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/UserDocs"];
if(![[NSFileManager defaultManager] fileExistsAtPath:folderPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:NO attributes:nil error:nil];
}
NSString *strFilePath = [folderPath stringByAppendingPathComponent:strFileName]; NSString *newFilePath = [NSString stringWithFormat:@"%@.%@", strFilePath, strFileExtension];
if(![[NSFileManager defaultManager] fileExistsAtPath:newFilePath]) {
[[NSFileManager defaultManager] createFileAtPath:newFilePath contents:nil attributes:nil];
}
self.fileHandle = [[NSFileHandle fileHandleForWritingAtPath:newFilePath] retain];
[self.fileHandle seekToFileOffset:0];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
[receivedData appendData:data];
NSUInteger chunkSize = 300000;
if( receivedData.length > chunkSize && self.fileHandle!=nil) {
NSData *chunk = [receivedData subdataWithRange:NSMakeRange(0, chunkSize)];
NSData *writableData = [[NSData alloc] initWithBase64EncodedData:chunk options:NSDataBase64DecodingIgnoreUnknownCharacters];
[receivedData replaceBytesInRange:NSMakeRange(0, chunkSize) withBytes:NULL length:0];
[self.fileHandle seekToEndOfFile];
[self.fileHandle writeData:writableData];
[writableData release];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
if (receivedData)
{
NSData *writableData = [[NSData alloc] initWithBase64EncodedData:receivedData options:NSDataBase64DecodingIgnoreUnknownCharacters];
[receivedData release];
[self.fileHandle seekToEndOfFile];
[self.fileHandle writeData:writableData];
[writableData release];
NSLog(@"File Write Success!!");
}
}
兩種可能的方法:
基本上:
#include <sys/stat.h>
#include <sys/mman.h>
...
NSURL *url = // path to file on disk
char *path = [url fileSystemRepresentation];
struct stat buf;
// Round up to an exact multiple of the page size
NSUInteger size = (buf.st_size + PAGE_MASK) & ~PAGE_MASK;
NSData *data = nil;
if (!stat(path, &buf)) {
int fd = open(path, O_RDONLY);
if (fd != -1) {
mmap(NULL, size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
data = [NSData dataWithBytesNoCopy:buf length:buf.st_size];
}
}
// Perform a base64 decode on the NSData object and hope that
// at least the result will fit in RAM.
// Clean up.
data = nil;
if (!stat(path, &buf)) {
int fd = open(path, O_RDONLY);
if (fd != -1) {
munmap(addr, size);
}
}
剩下的工作就是創建一個base64解碼器,該解碼器可以將數據直接寫到磁盤上的文件中,作為讀者的一項練習。 :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.