Ben Copsey

Optimise appendPostDataFromFile: to remove temporary memory use spike

Fiddle with iPhone upload sample to demonstrate file streaming
... ... @@ -213,18 +213,18 @@ static NSError *ASIUnableToCreateRequestError;
[self setupPostBody];
NSInputStream *stream = [[[NSInputStream alloc] initWithFileAtPath:file] autorelease];
[stream open];
NSMutableData *d;
int bytesRead;
while ([stream hasBytesAvailable]) {
d = [NSMutableData dataWithLength:256*1024];
int bytesRead = [stream read:[d mutableBytes] maxLength:256*1024];
unsigned char buffer[1024*256];
bytesRead = [stream read:buffer maxLength:sizeof(buffer)];
if (bytesRead == 0) {
break;
}
[d setLength:bytesRead];
if ([self shouldStreamPostDataFromDisk]) {
[[self postBodyWriteStream] write:[d mutableBytes] maxLength:bytesRead];
[[self postBodyWriteStream] write:buffer maxLength:bytesRead];
} else {
[[self postBody] appendData:[NSData dataWithBytes:[d mutableBytes] length:bytesRead]];
[[self postBody] appendData:[NSData dataWithBytes:buffer length:bytesRead]];
}
}
[stream close];
... ...
... ... @@ -30,7 +30,17 @@
[request setPostValue:@"test" forKey:@"value2"];
[request setPostValue:@"test" forKey:@"value3"];
[request setTimeOutSeconds:20];
[request setData:[NSMutableData dataWithLength:1024*1024] forKey:@"1mb-of-crap"];
//Create a 256KB file
NSData *data = [[[NSMutableData alloc] initWithLength:256*1024] autorelease];
NSString *path = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"file"];
[data writeToFile:path atomically:NO];
//Add the file 8 times to the request, for a total request size around 4MB
int i;
for (i=0; i<16; i++) {
[request setFile:path forKey:[NSString stringWithFormat:@"file-%hi",i]];
}
[networkQueue addOperation:request];
[networkQueue go];
... ...
This diff was suppressed by a .gitattributes entry.