2013-09-27 8 views
6
केवल मौजूदा फ़ाइलों

मूल रूप से मैं कोको एपीआई के साथ फाइल सिस्टम में दो फ़ोल्डर मर्ज करने के लिए एक तरह से देख रहा हूँ के ऊपर लिख:NSFileManager के साथ फ़ोल्डर मर्ज,

मैं फ़ाइलों और उप-फ़ोल्डर, जो मैं चाहता हूँ वाला कोई फ़ोल्डर है फाइल सिस्टम में एक अलग स्थान पर कॉपी करें।
मेरे गंतव्य पथ पर, एक समान नामित फ़ोल्डर पहले से मौजूद है, जिसमें फाइलें और फ़ोल्डर्स भी हो सकते हैं।

अब मैं अपने स्रोत फ़ोल्डर की नई सामग्री के साथ अपने गंतव्य फ़ोल्डर (या इसके उपफोल्डर) के अंदर मौजूदा फ़ाइलों को ओवरराइट करना चाहता हूं, यदि उनके पास समान नाम है।
बाकी सभी फाइलें जिन्हें मैं बिना छूना छोड़ना चाहता हूं।

sourcefolder 
    | 
    - file1 
    - subfolder 
     - file2 


destinationfolder 
    | 
    - file3 
    - subfolder 
     - file2 
     - file4 


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

मैं यह कैसे कर सकता हूं? आपकी मदद के लिए बहुत बहुत धन्यवाद!

उत्तर

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

में एक समाधान '' enumeratorAtPath विधि इतना महान काम करता है। –

+0

आप कमाल हैं !!! मुझे एक टन बचाया :) – jj080808

1

देखो और डिफ़ॉल्ट फ़ाइल प्रबंधक का उपयोग करने के बजाय, alloc/init साथ अपने स्वयं के बनाने के लिए, एक प्रतिनिधि निर्धारित करते हैं, और प्रतिनिधि तरीकों का उपयोग।

+0

सुझाव के लिए धन्यवाद! मैंने यह भी पाया कि अन्य विधियां हैं जो इसे और अधिक साफ कर सकती हैं। मैं अपना जवाब संपादित करूंगा। – Hlung

2

स्विफ्ट 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 
     } 
    } 
} 
संबंधित मुद्दे