I've been struggling to find a solution to do what should be a very simple task. I need to move a certain type of file (all zip files in this case) into another directory. I've tried NSTask and NSFileManager but have come up empty. I can move one at a time, but I would like to move them in one shot, at the same time.
- (void)copyFilesTo :(NSString*)thisPath {
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:thisPath];
NSString *filename = nil;
while ((filename = [direnum nextObject] )) {
if ([filename hasSuffix:@".zip"]) {
[fileManager copyItemAtPath:thisPath toPath:newPath];
}
}
}
FAILED - files copied = zeroooo
- (void)copyFilesMaybe :(NSString*)thisPath {
newPath = [newPath stringByAppendingPathComponent:fileName];
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/find"];
[task waitUntilExit];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: thisPath, @"-name", @"*.zip", @"-exec", @"cp", @"-f", @"{}", newPath, @"\\", @";", nil];
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
}
Same sad result, no files copied. What the heck am I doing wrong?
In the first case, you aren't using filename
in your copy call. You need to construct a full path to the file by combining filename
with thisPath
and attempting to copy that. Also, the method is -copyItemAtPath:toPath:error:
. You left off the last parameter. Try:
NSError* error;
if (![fileManager copyItemAtPath:[thisPath stringByAppendingPathComponent:filename] toPath:newPath error:&error])
// handle error (at least log error)
In the second case, I think your arguments
array is wrong. I'm not sure why it includes @"\\"
. I suspect because at a shell you have to escape the semicolon with a backslash (\;
). However, the need to escape the semicolon is because the shell would otherwise interpret it and not pass it to find
. Since you're not using a shell, you don't need to do that. (Also, if you did need to escape it, it shouldn't be a separate element of the arguments array. It would be in the same element as the semicolon, like @"\\;"
.)
Also, are you sure the task has completed? You show the launch but you don't show observing or waiting for its termination. Given that you've set a pipe for its output, you have to read from that pipe to be sure that the subprocess isn't getting stuck writing to it.
I'm not sure why you're calling -waitUntilExit
before launching the task. That may be harmless, though.