【问题标题】:NSFileManager list directory contents excluding directoriesNSFileManager 列出目录内容,不包括目录
【发布时间】:2013-08-04 09:29:30
【问题描述】:

有没有办法告诉-[NSFileManager contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:] 方法在收集目录内容时排除目录名称?

我有一个显示文件夹的树视图,并且只想在表格视图中显示文件,但我似乎找不到键或任何其他方式来排除文件夹。我想我可以迭代返回的数组以仅将文件填充到第二个数组中,该数组将用作数据源,但是这种双重处理似乎有点狡猾。

如果NSURL 是一个目录,我也尝试从tableView:viewForTableColumn:row: 方法返回nil,但这只会导致表中出现空白行,所以这也不好。

肯定有办法告诉NSFileManager 我只想要文件吗?

【问题讨论】:

    标签: objective-c cocoa nsfilemanager


    【解决方案1】:

    没有办法获得包括目录在内的内容,然后从那里削减它们,但这不是真正的问题。

    您从文件管理器获得的NSURLs 会告诉您每个代表的文件系统对象是否是一个目录,只要您在“键的属性”列表中包含NSURLIsDirectoryKey 项。

    在您获得该信息后,有多种方法可以使用该信息过滤数组 - 或者通过枚举,如其他答案所示。

    你可以给NSURL添加一个访问器方法:

    @implementation NSURL (RWIsDirectory)
    
    - (BOOL)RWIsDirectory
    {
        NSNumber * isDir;
        [self getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:NULL];
        return [isDir boolValue];
    }
    
    @end
    

    然后使用谓词:

    [directoryContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"RWIsDirectory == NO"]];
    

    【讨论】:

      【解决方案2】:

      最好的选择是使用enumeratorAtURL:includingPropertiesForKeys:options:errorHandler: 来填充排除文件夹的数组。

      NSFileManager *fm = [[NSFileManager alloc] init];
      NSDirectoryEnumerator *dirEnumerator = [fm enumeratorAtURL:directoryToScan
                          includingPropertiesForKeys:@[ NSURLNameKey, NSURLIsDirectoryKey ]
                          options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsSubdirectoryDescendants
                          errorHandler:nil];
      
      NSMutableArray *fileList = [NSMutableArray array];
      
      for (NSURL *theURL in dirEnumerator) {
          NSNumber *isDirectory;
          [theURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
          if (![isDirectory boolValue]) {
              [fileList addObject:theURL];
          }
      }
      

      这将为您提供代表文件的 NSURL 对象数组。

      【讨论】:

      • 感谢您在我落后 10 秒后得出完全相同的答案。
      【解决方案3】:

      您可以更深入地使用目录枚举器。

      这个怎么样?

      NSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:directoryToScan includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLNameKey, NSURLIsDirectoryKey,nil] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants  errorHandler:nil];
      NSMutableArray *theArray=[NSMutableArray array];
      
      for (NSURL *theURL in dirEnumerator) {
      
          // Retrieve the file name. From NSURLNameKey, cached during the enumeration.
          NSString *fileName;
          [theURL getResourceValue:&fileName forKey:NSURLNameKey error:NULL];
      
          // Retrieve whether a directory. From NSURLIsDirectoryKey, also
          // cached during the enumeration.
      
          NSNumber *isDirectory;
          [theURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
      
      
          if([isDirectory boolValue] == NO)
          {
              [theArray addObject: fileName];
          }
      }
      
      // theArray at this point contains all the filenames
      

      【讨论】:

      • +1 以几乎相同的答案击败我 10 秒。 :)
      • 谢谢你。我想避免双重处理,但如果这是公认的做法,那么如果我知道我没有犯一些草率的编码违规行为,我可以忍受它。也谢谢大家。我没有足够的经验点来投票给任何人,但我非常感谢提供的所有解决方案。
      • 你可以只做“![isDirectory boolValue]”,布尔值不需要与if语句的文字进行比较。
      猜你喜欢
      • 2011-02-15
      • 2012-07-08
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2014-08-23
      相关资源
      最近更新 更多