How to transfer large files/directories over network using AsyncSocket

2.7k views Asked by At

I've tried the NSTask > NSData method, but the CPU/memory overhead is extremely large for anything over 1GB, so I need to find a way to do this like, say, an FTP server does it.

EDIT: How does remote desktop's copy files do it?

1

There are 1 answers

2
Aditya Vaidyam On BEST ANSWER

I think I got it. I had to read it into the memory in small byte-size (HAHA GET THE PUN?) pieces and transfer it over that way. Keep in mind that this only works for files, not directories. I tested it on a 450MB file and it copied in about 3 minutes with the exact same byte count as the source. It was a video, and while I was streaming it to the client, I was able to play it as well. Nifty, huh?

Without further ado, here's the code I used, slightly patched up to do a simple file-copy instead of over the network.

[[NSFileManager defaultManager] createFileAtPath:@"/path/to/file/dest" contents:nil attributes:nil];
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:@"/path/to/file/dest"];

uint64 offset = 0;
uint32 chunkSize = 8192;


NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/file/source"];
NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init];
NSData *data = [handle readDataOfLength:chunkSize];

NSLog(@"Entering Loop.");

while ([data length] > 0) {
    [output seekToEndOfFile];
    [output writeData:data];
    offset += [data length];

    NSLog(@"Switching Loop.");

    [autoreleasePool release];
    autoreleasePool = [[NSAutoreleasePool alloc] init];

    [handle seekToFileOffset:offset];
    data = [handle readDataOfLength:chunkSize];
}

NSLog(@"Exited Loop.");

[handle closeFile];
[autoreleasePool release];

[output closeFile];
[output release];