基本上我正在寻找一种方法来将文件系统中的两个文件夹与cocoa API合并:
我有一个包含文件和子文件夹的文件夹,我想将其复制到文件系统中的其他位置 在我的目标路径中,已经存在一个同名文件夹,它也可能包含文件和文件夹。
现在我想用我的源文件夹的新内容覆盖目标文件夹(或其子文件夹)中的现有文件,如果它们具有相同的名称。
我想要保留的所有其余文件都不会受到影响。
sourcefolder
|
- file1
- subfolder
- file2
destinationfolder
|
- file3
- subfolder
- file2
- file4
resultingfolder
|
- file1
- file3
- subfolder
- file2 <-- version from source folder
- file4
我该怎么做? 非常感谢你的帮助!
答案 0 :(得分:7)
我到处搜索但什么也没找到。所以我利用NSDirectoryEnumerator
提出了自己的解决方案。这应该适用于图表(覆盖旧文件)。希望它有所帮助。
- (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;
}
}
}
}
答案 1 :(得分:3)
Swift 3中的解决方案
let merger = FoldersMerger(actionType: .copy, conflictResolution: .keepSource)
merger.merge(atPath: sourceFolder, toPath: destinationFolder)
class FoldersMerger {
enum ActionType { case move, copy }
enum ConflictResolution { case keepSource, keepDestination }
private let fileManager = FileManager()
private var actionType: ActionType!
private var conflictResolution: ConflictResolution!
private var deleteEmptyFolders: Bool!
init(actionType: ActionType = .move, conflictResolution: ConflictResolution = .keepDestination, deleteEmptyFolders: Bool = false) {
self.actionType = actionType
self.conflictResolution = conflictResolution
self.deleteEmptyFolders = deleteEmptyFolders
}
func merge(atPath: String, toPath: String) {
let pathEnumerator = fileManager.enumerator(atPath: atPath)
var folders: [String] = [atPath]
while let relativePath = pathEnumerator?.nextObject() as? String {
let subItemAtPath = URL(fileURLWithPath: atPath).appendingPathComponent(relativePath).path
let subItemToPath = URL(fileURLWithPath: toPath).appendingPathComponent(relativePath).path
if isDir(atPath: subItemAtPath) {
if deleteEmptyFolders! {
folders.append(subItemAtPath)
}
if !isDir(atPath: subItemToPath) {
do {
try fileManager.createDirectory(atPath: subItemToPath, withIntermediateDirectories: true, attributes: nil)
NSLog("FoldersMerger: directory created: %@", subItemToPath)
}
catch let error {
NSLog("ERROR FoldersMerger: %@", error.localizedDescription)
}
}
else {
NSLog("FoldersMerger: directory %@ already exists", subItemToPath)
}
}
else {
if isFile(atPath:subItemToPath) && conflictResolution == .keepSource {
do {
try fileManager.removeItem(atPath: subItemToPath)
NSLog("FoldersMerger: file deleted: %@", subItemToPath)
}
catch let error {
NSLog("ERROR FoldersMerger: %@", error.localizedDescription)
}
}
do {
try fileManager.moveItem(atPath: subItemAtPath, toPath: subItemToPath)
NSLog("FoldersMerger: file moved from %@ to %@", subItemAtPath, subItemToPath)
}
catch let error {
NSLog("ERROR FoldersMerger: %@", error.localizedDescription)
}
}
}
if deleteEmptyFolders! {
folders.sort(by: { (path1, path2) -> Bool in
return path1.characters.split(separator: "/").count < path2.characters.split(separator: "/").count
})
while let folderPath = folders.popLast() {
if isDirEmpty(atPath: folderPath) {
do {
try fileManager.removeItem(atPath: folderPath)
NSLog("FoldersMerger: empty dir deleted: %@", folderPath)
}
catch {
NSLog("ERROR FoldersMerger: %@", error.localizedDescription)
}
}
}
}
}
private func isDir(atPath: String) -> Bool {
var isDir: ObjCBool = false
let exist = fileManager.fileExists(atPath: atPath, isDirectory: &isDir)
return exist && isDir.boolValue
}
private func isFile(atPath: String) -> Bool {
var isDir: ObjCBool = false
let exist = fileManager.fileExists(atPath: atPath, isDirectory: &isDir)
return exist && !isDir.boolValue
}
private func isDirEmpty(atPath: String) -> Bool {
do {
return try fileManager.contentsOfDirectory(atPath: atPath).count == 0
}
catch _ {
return false
}
}
}
答案 2 :(得分:1)
查看文件管理器方法,而不是使用默认文件管理器,使用alloc / init创建自己的方法,设置委托,并使用委托方法。