ken*_*nyc 5 url macos cocoa core-foundation appkit
在 macOS 10.12 中,NSURLCanonicalPathKey
被添加到NSURL
. 文档指出:
\n\n\nURL 的路径作为规范的绝对文件系统路径。
\n
除此之外,我看到的唯一其他文档/信息来自Swift 论坛帖子,其中指出:
\n\n\n\n\n您可能想查看 .canonicalPathKey (NSURLCanonicalPathKey)。在 Apple 平台上,许多标准 UNIXy 路径都存在于 /private/ 中,并具有来自根目录的相应符号链接。所以/etc/实际上是/private/etc/。如果您不\xe2\x80\x99t 规范化路径,您可能会因此而陷入困境。
\n
这对我来说似乎是一件大事,但令我惊讶的是它只在 10.12 中引入。我曾经只依赖NSURLPathKey
或.path
书签数据来解析 URL,但从来没有遇到过问题。
我现在应该在以前使用过的所有地方都使用规范路径\n标准路径值吗?
如果我将路径信息作为字符串存储在数据库中,我应该存储.path
or的值吗NSURLCanonicalPathKey
?
如果我将 转换NSURL
为字符串表示形式以在需要文件路径的 C/C++ 库中使用,我应该使用规范路径表示形式吗?
如果您要向用户显示文件的路径,是否应该显示规范路径?
与和NSURLCanonicalPathKey
相比如何,它们似乎做了相同的事情或相反的事情......(?)URLByStandardizingPath
URLByResolvingSymlinksInPath
这是在 macOS 10.14 上,我只考虑指向文件或文件夹的 URL。我知道书签数据可能应该存储在数据库中而不是路径中。
\n这取决于您计划如何使用该路径:
\n[NSURL fileURLWithPath:]
,那么您可以继续使用收到的常规路径,因为通常您会因为用户将其提供给而获得路径以某种方式改变你,然后最好不要改变它。[NSURL isEqual:]
则会出现false
- 如果您不喜欢这样,则必须对它们进行规范化。Unicode 标准化也可能很重要。例如,如果文件或文件夹使用预组合(NFC)字符,NSURL 方法会将它们转换为 NFD 字符串。OTOH,BSD/POSIX 函数不会这样做。因此,例如,如果您从 shell 命令获取路径,然后将它们与从 NSURL 获得的路径进行比较,则由于使用 NFC 和其他 NFD 字符,它们可能不会计算为相等。理想情况下,如果 NSURL 或 NSFileManager 涉及路径,那么您还应该首先通过 NSURL 传递 BSD 路径,以便最终获得具有相同组合格式的两种类型的路径。
\n输入 | URL按标准化路径 | NSURLCanonicalPathKey |
---|---|---|
/私人/var | /var | /私人/var |
/var | /var | /私人/var |
以下示例使用准备好的 APFS 卷,其中包含带有字母“\xc3\xbc”的预组合和分解表示形式的文件名以及符号链接。您可以在此处下载磁盘映像文件。
\n目录布局如下:
\n$ cd /Volumes/Canonical_Normalize_Test/\n$ ls -lR\ntotal 24\n-rw-r--r-- 1 user staff 19 Dec 29 19:27 decomposed_\xc3\xbc\n-rw-r--r-- 1 user staff 19 Dec 29 19:27 precomposed_\xc3\xbc\ndrwxr-xr-x 4 user staff 128 Dec 29 19:36 symlink_target_dir\nlrwxr-xr-x 1 user staff 18 Dec 29 19:36 symlink_to_dir -> symlink_target_dir\n-rwxr-xr-x@ 1 user staff 763 Dec 15 16:28 unicode_composition_check.sh\n\n./symlink_target_dir:\ntotal 0\nlrwxr-xr-x 1 user staff 17 Dec 29 19:36 decomposed_\xc3\xbc -> ../decomposed_\xc3\xbc\nlrwxr-xr-x 1 user staff 17 Dec 29 19:36 precomposed_\xc3\xbc -> ../precomposed_\xc3\xbc\n
Run Code Online (Sandbox Code Playgroud)\n文件“unicode_composition_check.sh”是一个脚本,用于创建两个“...\xc3\xbc”文件,一个使用 NFD 命名,另一个使用 NFC 命名(不幸的是,该脚本命名不正确)。
\n输入是:
\n/Volumes/Canonical_Normalize_Test/symlink_to_dir/precomposed_\\U00fc\n
Run Code Online (Sandbox Code Playgroud)\n(即路径包含目录符号链接并使用实际文件的 unicode 组成,即目标文件名的“\xc3\xbc”是预先组成的。)
\n方法 | 结果 |
---|---|
文件系统表示 | /Volumes/Canonical_Normalize_Test/symlink_to_dir/precomposed_u\\U0308 |
URL按标准化路径 | /Volumes/Canonical_Normalize_Test/symlink_to_dir/precomposed_u\\U0308 |
NSURLCanonicalPathKey | /Volumes/Canonical_Normalize_Test/symlink_target_dir/precomposed_u\\U0308 |
URLByResolvingSymlinksInPath | /Volumes/Canonical_Normalize_Test/precomposed_u\\U0308 |
我们看到每种方法都会给出不同的结果:
\n它们似乎都将路径标准化为 NFD,即“\xc3\xbc”在所有情况下都会被分解。对于常规的不区分大小写的卷来说,这是必要且正常的,因为文件名的查找是规范化不敏感的。但是:对于区分大小写的卷,不得更改其组成,虽然我没有对此进行测试,但我假设上述所有函数都将检测卷的区分大小写模式并相应地运行。
\n仅NSURLCanonicalPathKey
当我们想要稍后通过路径重新识别目标项时才给出所需的正确结果(与使用哪种 Unicode 组合以及路径是否包含指向目录的符号链接无关):它解析目录符号链接,但不解析最终符号链接那是在里面的symlink_target_dir
。如果它确实解析了最终路径元素(就像URLByResolvingSymlinksInPath
这样做),您将无法定位符号链接文件。
NSString\'sfileSystemRepresentation
不会更改路径(但对其进行规范化),而 NSURL\'sURLByStandardizingPath
在某些情况下会更改路径(例如,通过从某些根文件夹中删除“/private”)。
仅NSURLCanonicalPathKey
会根据实际的磁盘路径修复大小写。例如,从“/applications”创建的 URL 不会被任何其他函数转换为实际的“/Applications”路径。
如果您稍后需要重新识别路径,无论使用哪种表示形式(规范化、指向目录的符号链接),NSURLCanonicalPathKey
如果您需要保留实际项目(即使它是符号链接),请使用其中之一,或者使用URLByResolvingSymlinksInPath
始终识别给您的任何符号链接的目标。
但请注意(请参阅第一个示例),如果您使用URLByResolvingSymlinksInPath
,“/private/var/tmp”等将变成“/var/tmp”等,这是不常见的,因为它仍然包含符号链接(即“/变种”)。
另请记住,除非您获得规范路径,否则情况可能不正确。为了弥补这一点,比较路径要求您首先检查路径是否位于不区分大小写的卷上,以便您使用正确的比较选项(并且,作为一个额外的复杂性,只需将路径与“不区分大小写”的卷进行比较)对于 HFS+ 卷上的某些罕见脚本,选项可能不正确,因为它们使用较旧的 Unicode 标准,该标准具有与当前 macOS 版本使用的其他规则不同的规则。
\n最后,如果您只想查看两个路径是否指向同一个文件,那么使用不依赖路径的其他方法会更安全。看到这个答案。如果您需要持久记住文件位置,最好使用书签,这样即使用户同时重命名或移动文件,也可以找到它们。
\n免责声明:所有这些发现都是根据经验得出的,在 macOS 10.13.6 和 11.1(以及其间的系统)上进行了测试,因此您可能需要仔细检查我的发现,如果您得到不同的结果,请留下评论。
\n 归档时间: |
|
查看次数: |
392 次 |
最近记录: |