Wednesday, 11 September 2013

Objective-C File Copy Multithreading?

Objective-C File Copy Multithreading?

I am trying to write a program using Objective-C/XCode that backs up one
directory (source dir) into another (dest dir).
When I test the program on a small directory on my local machine, it works
as expected. But when I try a large directory, or anything over a network,
the program beachballs. I know that threading is the answer. Given the
following code one can tell I have been fiddling with various methods to
do this. Can anyone help out? I can't seem to get this working properly.
Here is the code/method in question:
- (void)doSync:(NSString *)sURL {
bStopCopy = NO;
NSString *sSource = [[pcSource URL] path];
NSString *sDestination = [[pcDestination URL] path];
NSString *sSourcePath = [sSource stringByAppendingString:@"/"];
NSString *sDestinationPath = [sDestination stringByAppendingString:@"/"];
NSString *sSourceFile;
NSString *sDestinationFile;
NSString* file;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager]
enumeratorAtPath:sURL];
while ((file = [enumerator nextObject]) && (bStopCopy == NO)) {
[btMainWindowStopQuitButton setTitle: @"Stop..."];
[btMainWindowStopQuitButton setTag:1];
bCopyInProgress = YES;
__block NSError *eErrorMessage;
sSourceFile = [sSourcePath stringByAppendingString:file];
sDestinationFile = [sDestinationPath stringByAppendingString:file];
// check if it's a directory & exists at destination
BOOL isDirectory = NO;
BOOL isFileExistingAtDestination = NO;
__block BOOL isThereAnError = NO;
[[NSFileManager defaultManager] fileExistsAtPath: [NSString
stringWithFormat:@"%@/%@",sURL,file]
isDirectory: &isDirectory];
isFileExistingAtDestination = [[NSFileManager defaultManager]
fileExistsAtPath: sDestinationFile];
if (!isDirectory) {
if (!isFileExistingAtDestination) {
//
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
0), ^{
// if (![[NSFileManager defaultManager]
copyItemAtPath:sSourceFile toPath:sDestinationFile error:
&eErrorMessage]) {
// NSLog(@"File Copy Error: %@",
eErrorMessage);
// isThereAnError = YES;
// }
// });
//[oqFileCopy addOperationWithBlock:^{
dispatch_queue_t copyQueue = dispatch_queue_create("Copy
File", NULL);
dispatch_async(copyQueue, ^{
if (![[NSFileManager defaultManager]
copyItemAtPath:sSourceFile toPath:sDestinationFile error:
&eErrorMessage]) {
NSLog(@"File Copy Error: %@", eErrorMessage);
isThereAnError = YES;
}
//[oqMain addOperationWithBlock:^{
dispatch_async(dispatch_get_main_queue(), ^{
llFileSize = [[[NSFileManager defaultManager]
attributesOfItemAtPath: sDestinationFile error: Nil]
fileSize];
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:@"%@\nCopied to: %@ (%qu
bytes)", [[tvDialogueLabel textStorage] string],
sDestinationFile, llFileSize]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel
string] length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
llTotalFileSize = llTotalFileSize + llFileSize;
});
});
// NSLog(@"%@", sSourceFile);
// NSLog(@"%@", sDestinationFile);
} else if (isFileExistingAtDestination) {
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:@"%@\nFile: %@ | Already Synced.",
[[tvDialogueLabel textStorage] string], sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string]
length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
}
}
else if (isDirectory) {
if (!isFileExistingAtDestination) {
if (![[NSFileManager defaultManager]
createDirectoryAtPath:sDestinationFile
withIntermediateDirectories:YES attributes:nil error:
&eErrorMessage]){
NSLog(@"Directory Create Failed: %@", eErrorMessage);
isThereAnError = YES;
}
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:@"%@\nCreated Directory: %@",
[[tvDialogueLabel textStorage] string], sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string]
length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
// NSLog(@"%@", sSourceFile);
// NSLog(@"%@", sDestinationFile);
} else if (isFileExistingAtDestination) {
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:@"%@\nDirectory: %@ | Already
Exists.", [[tvDialogueLabel textStorage] string],
sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string]
length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
}
[self doSync: file];
}
if (isThereAnError) {
NSLog(@"There was an error!");
//[_wDialogue setTitle: @"Error while syncing..."];
break;
}
// NSLog(@"%@",
@"==================================================");
}
}

No comments:

Post a Comment