admin管理员组文章数量:1302333
It appears that [NSURL fileReferenceURL]
returns the same information as calling [NSURL getResourceValue:forKey:error:]
for the key NSURLFileResourceIdentifierKey
.
Are they indeed functionally the same? (Spoiler: No, they aren't!)
It appears that [NSURL fileReferenceURL]
returns the same information as calling [NSURL getResourceValue:forKey:error:]
for the key NSURLFileResourceIdentifierKey
.
Are they indeed functionally the same? (Spoiler: No, they aren't!)
Share Improve this question asked Feb 10 at 15:38 Thomas TempelmannThomas Tempelmann 12.1k11 gold badges88 silver badges166 bronze badges1 Answer
Reset to default 6There is a fine but important difference between the two - they behave differently if the item is a hard linked file.
If, especially on a APFS formatted volume, you have multiple hard links for the same file content, then
NSURLFileResourceIdentifierKey
will return the same value (classic "inode") for all these hard links, whereasfileReferenceURL
returns unique "link IDs" that keep the reference for each hard link entry's path.
In depth
APFS manages two "inode" values for hard links:
The classic
inode
is the one that points to the file content. So, if multiple hard links point to the same content, you get that content's inode number. That's what thestat()
function and thestat
command line tool will show as well, BTW.The
linkID
is another inode, but this time it points to the directory entry (which, for non-hardlinked files is identical to the content inode). This value can be retrieved with thegetattrlist()
function, using theATTR_CMNEXT_LINKID
key. Additionally, since macOS 10.13, thesearchfs()
function can also return this value along with the classic inode number.
Resolving an inode or a link ID
Invoke fsgetpath
by declaring the following:
#include <sys/syscall.h>
#define fsgetpath(buf, bufsize, fsid, objid) \
(ssize_t)syscall(SYS_fsgetpath, buf, (size_t)bufsize, fsid, (uint64_t)objid)
Call it like this:
uint64_t inode = 2; // set this to the linkID or inode
const char *volPath = "/"; // must be set to the file's volume!
struct statfs fsinfo;
int err = statfs (volPath, &fsinfo);
if (err == 0) {
char path[MAXPATHLEN+1];
ssize_t len = fsgetpath (path, sizeof(path)-1, &fsinfo.f_fsid, inode);
if (len > 0) {
... process the path
}
}
To determine the correct volume, ideally at the time of storing the inode value, you can call stat()
and pass the file's full path and then store the returned st_dev
value or call statfs()
as shown above.
版权声明:本文标题:macos - What is the difference between fileReferenceURL and NSURLFileResourceIdentifierKey - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741707826a2393663.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论