【前言】
开发中遇到两个需求,是NSFileManager文件操作。
我有一个包含文件和子文件夹的A文件夹,我想将其复制到文件系统中的B文件夹下。在B中,可能已存在同名文件夹/文件,该文件夹也可能包含文件和文件夹。
【需求一】
我想用我A文件夹下所有文件移动到B文件夹下面,如果它们具有相同的名称,覆盖并替换B里面的同名文件,而B其余文件都不会受到影响。
【需求二】
我想用我A文件夹下所有文件复制到B文件夹下面,如果它们具有相同的名称,覆盖并替换B里面的同名文件,而B其余文件都不会受到影响。
【移动并合并文件】
根据需求如下文件操作简图:
Afolder
|
- file1
- subfolder
- file2
Bfolder
|
- file3
- subfolder
- file2
- file4
resultfolder
|
- file1
- file3
- subfolder
- file2 <-- version from Afolder
- file4
代码如下:
- (void)mergeContentsOfPath:(NSString *)srcDir intoPath:(NSString *)dstDir error:(NSError**)err {
NSLog(@"- mergeContentsOfPath: %@\n intoPath: %@", srcDir, dstDir);
NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *srcDirEnum = [fm enumeratorAtPath:srcDir];
NSString *subPath;
while ((subPath = [srcDirEnum nextObject])) {
NSLog(@" subPath: %@", subPath);
NSString *srcFullPath = [srcDir stringByAppendingPathComponent:subPath];
NSString *potentialDstPath = [dstDir stringByAppendingPathComponent:subPath];
// Need to also check if file exists because if it doesn't, value of `isDirectory` is undefined.
BOOL isDirectory = ([[NSFileManager defaultManager] fileExistsAtPath:srcFullPath isDirectory:&isDirectory] && isDirectory);
// Create directory, or delete existing file and move file to destination
if (isDirectory) {
NSLog(@" create directory");
[fm createDirectoryAtPath:potentialDstPath withIntermediateDirectories:YES attributes:nil error:err];
if (err && *err) {
NSLog(@"ERROR: %@", *err);
return;
}
}
else {
if ([fm fileExistsAtPath:potentialDstPath]) {
NSLog(@" removeItemAtPath");
[fm removeItemAtPath:potentialDstPath error:err];
if (err && *err) {
NSLog(@"ERROR: %@", *err);
return;
}
}
NSLog(@" moveItemAtPath");
[fm moveItemAtPath:srcFullPath toPath:potentialDstPath error:err];
if (err && *err) {
NSLog(@"ERROR: %@", *err);
return;
}
}
}
}
【复制并合并文件】
关于如何判定全部复制成功呢?我这边通过谓词和数组对比来实现。
通过遍历两个文件夹,得到所有文件名称,进行数组去重即可。
typedef void(^resultBackBlock)(BOOL isSucess);
- (void)viewDidLoad {
[super viewDidLoad];
NSString * documentDir =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
NSString *oldPicPath = [documentDir stringByAppendingPathComponent:@"AImageIcon"];
NSString *newPicPath = [documentDir stringByAppendingPathComponent:@"BImageIcon"];
//图片复制并合并
[self copyFileFromPath:oldPicPath toPath:newPicPath complete:^(BOOL isSucess) {
if (isSucess) { complete(YES); return; }else{ complete(NO); return; }
} ];
}
// 复制并合并文件夹
-(void)copyFileFromPath:(NSString *)sourcePath
toPath:(NSString *)toPath
complete:(resultBackBlock)complete{
// 1、得到文件路径
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray* arraySor = [fileManager contentsOfDirectoryAtPath:sourcePath error:nil];
if (arraySor.count == 0 ) { complete(YES); return; }
// 2、遍历并复制文件到新文件夹
for(int i = 0; i<[arraySor count]; i++){
NSString *fullPath = [sourcePath stringByAppendingPathComponent:[arraySor objectAtIndex:i]];
NSString *fullToPath = [toPath stringByAppendingPathComponent:[arraySor objectAtIndex:i]];
//判断是不是文件夹
BOOL isFolder = NO;
//判断是不是存在路径 并且是不是文件夹
BOOL isExist = [fileManager fileExistsAtPath:fullPath isDirectory:&isFolder];
if (isExist){
NSError *err = nil;
[[NSFileManager defaultManager] copyItemAtPath:fullPath toPath:fullToPath error:&err];
if (err!=nil) { NSLog(@"===%@===%@===错误日志", err, [err userInfo]);}
if (isFolder){ [self copyFileFromPath:fullPath toPath:fullToPath complete:^(BOOL isSucess) { }]; }
}
}
// 3、判断一个数组是否包含另一个数组的所有元素,谓词。
NSArray* arrayTo = [fileManager contentsOfDirectoryAtPath:toPath error:nil];
NSArray * filterList = [arraySor filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",arrayTo]];
if (filterList.count == 0) { complete(YES); return; }else{ complete(NO); return; }
}









网友评论