2013-09-27 11 views
6

üzerine yazmak, NSFileManager ile klasörleri birleştir dosya sistemindeki farklı bir yere kopyalayın.
Hedef yolumda, dosya ve klasörleri de içerebilen eşit olarak adlandırılmış bir klasör zaten var.Temelde kakao API ile dosya sisteminde iki klasörü birleştirmek için bir yol arıyorum sadece mevcut dosyalar

Şimdi, hedef klasörümün (veya alt klasörlerinin) içindeki varolan dosyaların üzerine, aynı ada sahiplerse, kaynak klasörümün yeni içeriğiyle yazmak istiyorum.
Tüm dosyalar el değmeden çıkmak istiyorum.

sourcefolder 
    | 
    - file1 
    - subfolder 
     - file2 


destinationfolder 
    | 
    - file3 
    - subfolder 
     - file2 
     - file4 


resultingfolder 
    | 
    - file1 
    - file3 
    - subfolder 
     - file2  <-- version from source folder 
     - file4 

Bunu nasıl yapabilirim? Yardımlarınız için çok teşekkürler!

cevap

7

Her yerde aradım ama hiçbir şey bulamadım. Bu yüzden kendi çözümümle, NSDirectoryEnumerator'u kullanarak geldim. Bu şema üzerinde çalışmalıdır (eski dosyaları geçersiz kılar). Umarım yardımcı olur.

- (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; 
      } 
     } 
    } 
} 
+0

bir çözelti 'enumeratorAtPath' yöntem çok büyük çalışır. –

+0

Harikasınız! Bana bir ton zaman kaydettim :) – jj080808

1

dosya yöneticisi yöntemlerine bakın ve bunun yerine varsayılan dosya yöneticisini kullanarak, ayırma/init ile kendi oluşturmak, bir temsilci ayarlayın ve temsilci yöntemleri kullanın.

+0

Öneri için teşekkürler! Ayrıca kendimi, bunu daha temiz bir şekilde yapabilecek başka yöntemler olduğunu öğrendim. Cevabımı düzenleyeceğim. – Hlung

2

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 
     } 
    } 
} 
İlgili konular