2

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?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Aditya Vaidyam
  • 6,259
  • 3
  • 24
  • 26
  • I'll let someone else elaborate on an official answer, but the way I would solve a problem like this would be to have a maximum size (for a buffer, or a `NSData` object) and then do the transfer in sequential increments. – Michael Dautermann Jan 11 '12 at 05:20
  • Since my app is a client-sever app, could I possible write an FTP server with single authentication, and have the clients connect to that on the side and download it? – Aditya Vaidyam Jan 11 '12 at 05:57
  • Well sure... you can do any kind of file transfer you want (FTP, TCP, UDP, two tin cans tied together with a string, etc.). As you're the programmer, you get to decide how best to implement file transfers. :-) – Michael Dautermann Jan 11 '12 at 06:00
  • HAHA, true that, but I'm trying to emulate how Remote Desktop does it... for example, if I were to install a package, i'd need to copy it over first, then i'd need to install. If I did the copy separately, then the install wouldn't work, and so on. The real question is how can I do it (the tasks) serially without hanging, or CPU overload? – Aditya Vaidyam Jan 11 '12 at 06:02

1 Answers1

3

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];
Aditya Vaidyam
  • 6,259
  • 3
  • 24
  • 26