Macos 使用进度条快速扫描磁盘中的文件

Macos 使用进度条快速扫描磁盘中的文件,macos,cocoa,filesystems,Macos,Cocoa,Filesystems,我需要搜索一个文件夹(和所有子文件夹)中的某些文件。这需要尽快完成,我需要能够向用户显示进度指示器 要显示进度指示器,我需要快速检索,例如,正在搜索的文件夹下的文件夹总数。这样,我可以在扫描子文件夹时对其进行计数,并向用户报告有用的内容 这些信息在什么地方有吗 请注意,此功能专门用于未使用Spotlight编制索引的磁盘。对于Spotlight索引驱动器,我只运行一个NSMetadataQuery。也许您可以使用NSDirectoryEnumarator进行查询 您可以在枚举器上检查文件总数,然

我需要搜索一个文件夹(和所有子文件夹)中的某些文件。这需要尽快完成,我需要能够向用户显示进度指示器

要显示进度指示器,我需要快速检索,例如,正在搜索的文件夹下的文件夹总数。这样,我可以在扫描子文件夹时对其进行计数,并向用户报告有用的内容

这些信息在什么地方有吗


请注意,此功能专门用于未使用Spotlight编制索引的磁盘。对于Spotlight索引驱动器,我只运行一个NSMetadataQuery。

也许您可以使用NSDirectoryEnumarator进行查询

您可以在枚举器上检查文件总数,然后在迭代时更新进度条

下面是检查所有子文件夹的一小段代码。它已经检查URL是否是目录,所以您可以忽略它

NSFileManager *fileManager = [[NSFileManager alloc] init] ;
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
NSString *path = @"YOUR PATH HERE"
NSMutableArray *files = [[NSMutableArray alloc] init];

NSDirectoryEnumerator *enumerator = [fileManager
                                     enumeratorAtURL:[NSURL fileURLWithPath:path]
                                     includingPropertiesForKeys:keys
                                     options:0
                                     errorHandler:^(NSURL *url, NSError *error) {
                                         // Handle the error.
                                         // Return YES if the enumeration should continue after the error.
                                         return YES;
                                     }];

for (NSURL *url in enumerator) {
    NSError *error;
    NSNumber *isDirectory = nil;
    if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
        // handle error
        NSLog(@"error-%@", error );
    }
    else if (! [isDirectory boolValue]) {
        //CHECK FOR YOUR FILES ON THIS URL AND UPDATE PROGRESS INDICATOR            
    }
}

对于实际扫描,您可以使用Cocoa类,如
NSDirectoryEnumerator
,或较低级别的工具,如
fts
——有多种方法可以选择最适合您的

更有趣的是你的进度指标。文件系统不维护文件夹的“子”计数,即所有子、孙、曾孙等的计数。但是,整个卷上的文件数是可用的,例如,请参见
statfs

特定文件夹中的项目数快速且易于确定;e、 g.
NSFileManager
目录路径的内容:错误:返回一个数组,
fts
例程返回一个链接列表,您甚至可以使用硬链接计数来计算它-可通过
NSURL
获取资源值:forKey:error:
获得。在进入目录时使用这些方法,您可以将其子计数添加到总数中,以便在扫描树时维护已处理的项目数和当前需要处理的已知数量。您的UI可以是“n/m”形式,两者都可以增加

如果您不喜欢,那么整个目录树中的项目数需要(预)扫描目录树,这需要一定的时间(您可以在Finder中看到这一点-只需选择任何文件夹,离磁盘根越近越好,然后执行“获取信息”,在收集信息时会看到暂停)。使用上述任何扫描方法都不难做到这一点。您必须考虑时间/值/内存折衷——例如,您可以说生成树中所有项的列表(目录枚举器将给出)。数一数,然后一次只处理一个项目,这样你就有可能占用大量内存,并在任何事情发生之前暂停—就像你在Finder的“获取信息”窗口中看到的暂停一样)

所以你的“快速进度条”目标是一个挑战


HTH

为了知道我扫描磁盘的距离,我必须知道有多少文件夹需要扫描…您正在查找文件或目录<代码>[[enumerator allObjects]count]提供您正在查看的文件数(&目录,因为它们是文件系统中的“文件”)。我不知道您想要完成什么。检查所有文件的实际步骤是需要检查的文件总数,而不是文件夹(和子文件夹)的数量。哦,我现在明白你的意思了。我写过“跳过目录”。实际上,代码并没有跳过目录,而是在所有子文件夹上运行代码并检查它是否是目录。如果它是一个目录,它将跳过(不要检查它是否是您的文件)并继续。刚刚更新了我的答案现在的问题是,我实际上需要扫描系统上与给定模式匹配的所有捆绑包。捆绑包是文件夹,因此如果我必须预先扫描才能获得文件夹计数,那么我最好同时进行扫描。@tarmes-这是一个合理的结论。考虑“m的n”类型的UI,而您可以不断增加图形进度指示器的限制,到目前为止,向后移动的进度可能会混淆。或者,将卷上的项目数作为上限,如果您只扫描一个文件夹而不是整个光盘,则可能会报告进度不足。