【问题标题】:NSFileManager delete contents of directoryNSFileManager 删除目录的内容
【发布时间】:2011-02-15 17:32:48
【问题描述】:

如何在不删除目录本身的情况下删除目录的所有内容?我想基本上清空一个文件夹,但保留它(和权限)完好无损。

【问题讨论】:

    标签: cocoa directory osx-snow-leopard nsfilemanager


    【解决方案1】:

    例如通过使用目录枚举器:

    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);
        }
    }
    

    斯威夫特

    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)
    }
    

    【讨论】:

    • 在尝试使用错误对象之前不要忘记检查removeItemAtPath: 是否真的失败了。至少,您报告的错误可能比实际报告的多。
    • 你的while循环有问题,你不能在while括号内声明你的变量!!
    • @Psycho:对于 Objective-C 来说是正确的,但对于 Objective-C++ 来说工作得很好。当这与问题无关且易于修复时,是否值得投反对票?我不这么认为......
    • 对解决方案投了反对票,只需通过保存权限而不是遍历内容来删除整个目录。
    【解决方案2】:

    您可以像这样扩展NSFileManager

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

    然后,您可以像这样清除文件夹:NSFileManager.defaultManager().clearFolderAtPath("the folder's path")

    【讨论】:

      【解决方案3】:

      Swift 3 如果有人需要它来快速剪切/粘贴

      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)
          }
      }
      

      【讨论】:

        【解决方案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 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")
              }
            }
          }
          

          【讨论】:

            【解决方案6】:

            Georg Fritzsche 对 Swift 的回答对我不起作用。不要将枚举对象读取为字符串,而是将其读取为 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)
            }
            

            【讨论】:

              【解决方案7】:

              试试这个:

              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...
                  }
              }    
              

              【讨论】:

              • contentsOfDirectoryAtPath:: 不会为您提供内容的完整路径。
              • 没有必要测试“。”或“..”,因为contentsOfDirectoryAtPath:error 过滤它们;来自 docs 搜索很浅,因此不返回任何子目录的内容。这个返回的数组不包含当前目录(“.”)、父目录(“..”)或资源分支(以“._”开头)的字符串,并且不遍历符号链接。跨度>
              • @petert 哇,这是一个非常古老的答案。感谢您的信息。
              【解决方案8】:

              contentsOfDirectoryAtPath:error: 的文档说:

              搜索很浅,因此不返回任何子目录的内容。这个返回的数组不包含当前目录(“.”)、父目录(“..”)或资源分支(以“._”开头)的字符串,并且不遍历符号链接。

              因此:

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

              无关紧要。

              【讨论】:

                【解决方案9】:

                为什么不删除整个目录然后重新创建呢?只需在删除之前获取文件属性和权限,然后使用相同的属性重新创建它。

                【讨论】:

                • 如果您可以删除文件夹的内容,为什么还要删除文件夹并遇到可能的问题(例如权限)?
                • 扫描目录并从源代码中删除文件通常会更好,因为它更可靠地恢复和报告错误。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-08-04
                • 2013-07-08
                • 2011-01-13
                • 1970-01-01
                • 1970-01-01
                • 2014-01-07
                相关资源
                最近更新 更多