NSFileManager delete contents of directory

2020-05-14 03:47发布

问题:

How do you delete all the contents of a directory without deleting the directory itself? I want to basically empty a folder yet leave it (and the permissions) intact.

回答1:

E.g. by using a directory enumerator:

NSFileManager *fileManager = [[NSFileManager alloc] init];
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:path];    
NSString *file;

while (file = [enumerator nextObject]) {
    NSError *error = nil;
    BOOL result = [fileManager removeItemAtPath:[path stringByAppendingPathComponent:file] error:&error];

    if (!result && error) {
        NSLog(@"Error: %@", error);
    }
}

Swift

let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtURL(cacheURL, includingPropertiesForKeys: nil, options: nil, errorHandler: nil)

while let file = enumerator?.nextObject() as? String {
    fileManager.removeItemAtURL(cacheURL.URLByAppendingPathComponent(file), error: nil)
}


回答2:

Try this:

NSFileManager *manager = [NSFileManager defaultManager];
NSString *dirToEmpty = ... //directory to empty
NSError *error = nil;
NSArray *files = [manager contentsOfDirectoryAtPath:dirToEmpty 
                                              error:&error];

if(error) {
  //deal with error and bail.
}

for(NSString *file in files) {
    [manager removeItemAtPath:[dirToEmpty stringByAppendingPathComponent:file]
                        error:&error];
    if(error) {
       //an error occurred...
    }
}    


回答3:

in swift 2.0:

if let enumerator = NSFileManager.defaultManager().enumeratorAtPath(dataPath) {
  while let fileName = enumerator.nextObject() as? String {
    do {
        try NSFileManager.defaultManager().removeItemAtPath("\(dataPath)\(fileName)")
    }
    catch let e as NSError {
      print(e)
    }
    catch {
      print("error")
    }
  }
}


回答4:

Swift 2.1.1:

public func deleteContentsOfFolder()
{
    // folderURL
    if let folderURL = self.URL()
    {
        // enumerator
        if let enumerator = NSFileManager.defaultManager().enumeratorAtURL(folderURL, includingPropertiesForKeys: nil, options: [], errorHandler: nil)
        {
            // item
            while let item = enumerator.nextObject()
            {
                // itemURL
                if let itemURL = item as? NSURL
                {
                    do
                    {
                        try NSFileManager.defaultManager().removeItemAtURL(itemURL)
                    }
                    catch let error as NSError
                    {
                        print("JBSFile Exception: Could not delete item within folder.  \(error)")
                    }
                    catch
                    {
                        print("JBSFile Exception: Could not delete item within folder.")
                    }
                }
            }
        }
    }
}


回答5:

Swift 3 if anyone needs it for a quick cut/paste

let fileManager = FileManager.default
let fileUrls = fileManager.enumerator(at: folderUrl, includingPropertiesForKeys: nil)
while let fileUrl = fileUrls?.nextObject() {
    do {
        try fileManager.removeItem(at: fileUrl as! URL)
    } catch {
        print(error)
    }
}


回答6:

The documentation for contentsOfDirectoryAtPath:error: says:

The search is shallow and therefore does not return the contents of any subdirectories. This returned array does not contain strings for the current directory (“.”), parent directory (“..”), or resource forks (begin with “._”) and does not traverse symbolic links.

Thus:

---( file != @"." && file != @".." )---

is irrelevant.



回答7:

You can extend the NSFileManager like this:

extension NSFileManager {
  func clearFolderAtPath(path: String) -> Void {
      for file in subpathsOfDirectoryAtPath(path, error: nil) as? [String] ?? []  {
          self.removeItemAtPath(path.stringByAppendingPathComponent(file), error: nil)
      }
  }
}

Then, you can clear the folder like this: NSFileManager.defaultManager().clearFolderAtPath("the folder's path")



回答8:

Georg Fritzsche answer for Swift did not work for me. Instead of reading the enumerated object as a String, read it as NSURL.

let fileManager = NSFileManager.defaultManager()
let url = NSURL(string: "foo/bar")
let enumerator = fileManager.enumeratorAtURL(url, includingPropertiesForKeys: nil, options: nil, errorHandler: nil)
while let file = enumerator?.nextObject() as? NSURL {
    fileManager.removeItemAtURL(file, error: nil)
}


回答9:

Why not deleting the whole directory and recreate afterwards? Just get the file attributes and permissions before deleting it, and then recreate it with the same attributes.