OSX Yosemite在NSURL上引入了一个非常方便的属性:NSURLDocumentIdentifierKey
。
从文档中引用:
NSURLDocumentIdentifierKey
作为NSNumber(只读)返回的文档标识符。 文档标识符是内核分配给文件或目录的值。此值用于标识文档,无论文档在卷上的位置如何。标识符在系统重新启动后仍然存在。复制文件时不会传输它,但它会在“安全保存”操作中继续存在。例如,即使在调用replaceItemAtURL后,它仍保留在分配给它的路径上:withItemAtURL:backupItemName:options:resulItemURL:error:method 。文档标识符在单个卷中是唯一的。所有卷都不支持此属性。
在OS X v10.10和iOS 8.0中可用。
不幸的是,这个值似乎大多为零(除了罕见的例子,看起来彼此完全断开)。
特别是,此代码将在最后一行抛出异常(在Yosemite 10.10.3上测试):
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *attributesFlags = @[NSURLNameKey, mNSURLDocumentIdentifierKey];
NSDirectoryEnumerator *en = [fileManager enumeratorAtURL:[NSURL URLWithString:NSHomeDirectory()]
includingPropertiesForKeys:attributesFlags
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:^BOOL(NSURL *url, NSError *error) {
NSAssert(NO, @"An error has occured");
return YES;
}];
for(NSURL *URL in en) {
NSNumber *documentID = nil;
NSError *error = nil;
BOOL result = [URL getResourceValue:&documentID forKey:NSURLDocumentIdentifierKey error:&error]; \
NSAssert(result == YES && error==nil, @"Unable to read property. Error: %@", error); \
NSLog(@"Processing file: %@", URL);
// This will break most of the times
NSAssert(documentID != nil, @"Document ID should not be nil!!");
}
也许我误解了文档,但在我看来NSURLDocumentIdentifierKey
应该可以在磁盘上的每个文件中使用。
答案 0 :(得分:2)
我在这个问题上向Apple提交了一个错误,并对我的报告得到了反馈。截至今天,跟踪DocumentIdentifier
的信息尚未成为文档的一部分,但机票仍然是开放的。
缺少的信息是文件系统默认不跟踪DocumentIdentifier
。您必须通过使用带有chflags
标记的UF_TRACKED
在要跟踪的每个文件上设置标记来启用跟踪。
以下脚本将打印文件的DocumentIdentifier
:
https://gist.github.com/cmittendorf/fac92272a941a9cc64d5
此脚本将启用跟踪DocumentIdentifier
:
答案 1 :(得分:0)
显然,Yosemite只有在知道某些内容正在尝试跟踪其身份(例如Versions或iCloud)时才会将 DocumentIdentifier 分配给文件。
我没有看到任何与内核交谈的方式,并告诉它开始跟踪你感兴趣的文件。我希望在将来的版本中发生这种变化,因为API已经在OS X 10.10上公开了,而且此时它几乎没用。
答案 2 :(得分:0)
macOS 10.14中仍然存在此问题。它可能不会改变。
解决方法是从NSFileManager
获取索引节点,如下所示:
NSFileManager *fmgr = [NSFileManager defaultManager];
NSDictionary *attributes = [fmgr attributesOfItemAtPath:url.path error:nil;
if (attributes != nil) {
NSNumber *inode = [attributes objectForKey:NSFileSystemFileNumber];
...
}