Oli*_*ney 9 upload base64 http ios
描述: 我需要在HTTP POST参数中发送一个base 64编码的字符串,该参数表示要上载的文件.
当前方法:我正在使用ASIFormDataRequest并将我的文件编码为base64字符串,如下所示:
NSData *data = [[NSFileManager defaultManager] contentsAtPath:@"my path here"];
NSString *base64Data = [data encodeBase64ForData];
Run Code Online (Sandbox Code Playgroud)
然而,当上传大文件时,应用程序内存不足并死于可怕的死亡!
建议的解决方案:现在是否有人会如何处理,比如从磁盘读取文件,将其转换为块中的base64字符串并将转换后的base64字符串附加到HTTP请求中的参数?
有效地避免将整个文件读入内存的任何方式.
任何投入将不胜感激!
我的http请求代码完整:
NSURL *url = [NSURL URLWithString:requestProgressURLString];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:evidence.uri];
NSString *base64Data = [data encodeBase64ForData];
NSURL *fileURL = [[NSURL alloc] initWithString:evidence.uri];
request = [ASIFormDataRequest requestWithURL:url];
request.shouldAttemptPersistentConnection = false;
[request setShowAccurateProgress:YES];
[request setPostValue:accessToken forKey:@"AccessToken"];
[request setPostValue:[[fileURL path] lastPathComponent] forKey:@"Filename"];
[request setPostValue:evidence.name forKey:@"Title"];
[request setPostValue:base64Data forKey:@"FileData"]; //wants string value (base64 encoded)
[request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
[request setTimeOutSeconds:60];
[request setUploadProgressDelegate:self];
[request setDownloadProgressDelegate:self];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
Run Code Online (Sandbox Code Playgroud)
您需要分块读取文件,而不是一次性读取文件
您可以使用输入流来执行此操作 Apple 在此处有一些信息
基本上,您需要创建一个指向您的文件的 NSInputStream,如示例中所示
- (void)setUpStreamForFile:(NSString *)path {
// iStream is NSInputStream instance variable
iStream = [[NSInputStream alloc] initWithFileAtPath:path];
[iStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用 NSStreamDelegate 方法读取块中的数据 - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
苹果再次举了一个例子
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if(!_data) {
_data = [[NSMutableData data] retain];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[_data appendBytes:(const void *)buf length:len];
// bytesRead is an instance variable of type NSNumber.
[bytesRead setIntValue:[bytesRead intValue]+len];
// DO SOMETHING with DATA HERE
} else {
NSLog(@"no buffer!");
}
break;
}
Run Code Online (Sandbox Code Playgroud)
您选择的块的大小需要在内存性能与网络性能之间取得平衡,因为 HTTP 标头显然会产生一些开销
您还可以通过直接发送 NSData 来进一步优化(从而节省 base64 开销)查看这篇文章
| 归档时间: |
|
| 查看次数: |
3934 次 |
| 最近记录: |