因此,我问,是否存在使用纯Cocoa代码复制文件的推荐方法.
可选:哪个命令行工具提供帮助,Cocoa应用程序可以使用它.
解决方法 您也可以使用 FSCopyObjectAsync功能.您可以显示文件复制进度,也可以使用FScopyObjectAsync()取消文件复制.看一下 FSFileOperation示例代码.
This sample shows how to copy and move both files and folders. It
shows both the synchronous and asynchronous (using CFRunLoop) use of
the FSfileOperation APIs. In addition,it shows path and FSRef
variants of the API and how to get status out of the callbacks. The
API is conceptually similar to the FSVolumeOperation APIs introduced
in Mac OS X 10.2.
FScopyObjectAsync的示例:
#import <Cocoa/Cocoa.h>@interface AsynccopyController : NSObject {}-(Osstatus)copySource : (Nsstring *)aSource ToDestination: (Nsstring *)aDestDir setDelegate : (ID)object;//delegate method-(voID)dIDReceiveCurrentPath : (Nsstring *)curremtItemPath bytesCompleted : (unsigned long long)floatBytesCompleted currentStageOffileOperation : (unsigned long)stage;-(voID)dIDcopyOperationComplete : (BOol)boolean;-(voID)dIDReceivecopyError : (Nsstring *)Error;-(voID)cancelAllAsynccopyOperation;@end #import "AsynccopyController.h"static Boolean copying= YES;@implementation AsynccopyControllerstatic voID statusCallback (FSfileOperationRef fileOp,const FSRef *currentItem,FSfileOperationStage stage,Osstatus error,CFDictionaryRef statusDictionary,voID *info ){ NSLog(@"Callback got called. %ld",error); ID delegate; if (info) delegate = (ID)info; if (error!=0) { if (error==-48) { [delegate dIDReceivecopyError:@"Duplicate filename and version or Destination file already exists or file found instead of folder"]; } } CFURLRef theURL = CFURLCreateFromFSRef( kcfAllocatorDefault,currentItem ); Nsstring* currentPath = [(NSURL *)theURL path];// NSLog(@"currentPath %@",currentPath); // If the status dictionary is valID,we can grab the current values to // display status changes,or in our case to update the progress indicator. if (statusDictionary) { CFNumberRef bytesCompleted; bytesCompleted = (CFNumberRef) CFDictionaryGetValue(statusDictionary,kFSOperationBytesCompleteKey); CGfloat floatBytesCompleted; CFNumberGetValue (bytesCompleted,kcfNumberMaxType,&floatBytesCompleted);// NSLog(@"copIEd %d bytes so far.",// (unsigned long long)floatBytesCompleted); if (info) [delegate dIDReceiveCurrentPath :currentPath bytesCompleted :floatBytesCompleted currentStageOffileOperation:stage]; } NSLog(@"stage %d",stage); if (stage == kFSOperationStageComplete) { NSLog(@"Finished copying the file"); if (info) [delegate dIDcopyOperationComplete:YES]; // Would like to call a Cocoa Method here... } if (!copying) { FSfileOperationCancel(fileOp); }} -(voID)cancelAllAsynccopyOperation{ copying = NO;}-(Osstatus)copySource : (Nsstring *)aSource ToDestination: (Nsstring *)aDestDir setDelegate : (ID)object{ NSLog(@"copySource"); copying = YES; CFRunLoopRef runLoop = CFRunLoopGetCurrent(); NSLog(@"%@",runLoop); FSfileOperationRef fileOp = FSfileOperationCreate(kcfAllocatorDefault); require(fileOp,FSfileOperationCreateFailed); Osstatus status = FSfileOperationScheduleWithRunLoop(fileOp,runLoop,kcfRunLoopDefaultMode); if (status) { NSLog(@"Failed to schedule operation with run loop: %@",status); return status; } require_noerr(status,FSfileOperationScheduleWithRunLoopFailed); if (status) { NSLog(@"Failed to schedule operation with run loop: %@",status); //return NO; } // Create a filesystem ref structure for the source and destination and // populate them with their respective paths from our NSTextFIElds. FSRef source; FSRef destination; // Used FSPathMakeRefWithOptions instead of FSPathMakeRef // because I needed to use the kFSPathMakeRefDefaultoptions // to deal with file paths to remote folders via a /Volume reference status = FSPathMakeRefWithOptions((const UInt8 *)[aSource fileSystemRepresentation],kFSPathMakeRefDefaultoptions,&source,NulL); require_noerr(status,FSPathMakeRefWithOptionsaSourceFailed); Boolean isDir = true; status = FSPathMakeRefWithOptions((const UInt8 *)[aDestDir fileSystemRepresentation],&destination,&isDir); require_noerr(status,FSPathMakeRefWithOptionsaDestDirFailed); // Needed to change from the original to use CFStringRef so I Could convert // from an Nsstring (aDestfile) to a CFStringRef (targetfilename) FSfileOperationClIEntContext clIEntContext; // The FSfileOperation will copy the data from the passed in clIEntContext so using // a stack based record that goes out of scope during the operation is fine. if (object) { clIEntContext.version = 0; clIEntContext.info = (voID *) object; clIEntContext.retain = CFRetain; clIEntContext.release = CFRelease; clIEntContext.copyDescription = CFcopyDescription; } // Start the async copy. status = FScopyObjectAsync (fileOp,// Full path to destination dir NulL,// Use the same filename as source kFSfileOperationDefaultoptions,statusCallback,1.0,object != NulL ? &clIEntContext : NulL); //CFRelease(fileOp); NSLog(@"Failed to begin asynchronous object copy: %d",status); if (status) { Nsstring * errMsg = [Nsstring stringWithFormat:@" - %@",status]; NSLog(@"Failed to begin asynchronous object copy: %d",status); } if (object) { [object release]; }FSfileOperationScheduleWithRunLoopFailed: CFRelease(fileOp);FSPathMakeRefWithOptionsaSourceFailed:FSPathMakeRefWithOptionsaDestDirFailed:FSfileOperationCreateFailed: return status;}@end
FScopyObjectAsync在OS X v10.8中已弃用
copyfile(3)是FScopyObjectAsync的替代方案. Here是具有Progress Callback的copyfile(3)的示例.
总结以上是内存溢出为你收集整理的objective-c – 使用Cocoa复制任意文件的推荐方法全部内容,希望文章能够帮你解决objective-c – 使用Cocoa复制任意文件的推荐方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)