NSURL 路径对绝对字符串

关于在 NSURLNSString之间进行转换,我已经看到了许多关于 SO 的问题。它们都涉及使用 NSString *path = [myURL absoluteString];NSString *path = [myURL path];。我尝试咨询 苹果文档,但我发现它不太有帮助。

我已经习惯了 URL 只在有关网站和其他主题的讨论中被提及,这些主题涉及到在不同的机器之间发送信息,而在处理单个机器上的文件结构时从未被提及。也许这就是我感到困惑的地方,因为 NSURL似乎是访问文件的首选方式,无论该文件是存在于网络上还是本地设备上。或许这是个完全不相关的话题。我都不确定。

43773 次浏览

问题一:

这些方法之间的实际区别是什么?

让我们来分析一下这个编写6行代码的过程——3行代码用于本地,3行代码用于 http URL ——并对它们进行一些处理。

让我们使用 file://方案创建一个 NSURL。如果你问自己为什么在 file:之后有3个 /,你应该记住一个完整的 URL 存在一个方案(file://和绝对或相对路径(你可以找到更多的信息创建在 RFC 1808在第三页的 URL)。我们使用一个以 /开始的绝对路径,这样我们就得到了 ///

NSURL *aLocalURL = [NSURL URLWithString:@"file:///Users/dennis/Desktop/"];
NSLog(@"absolute string: %@", aLocalURL.absoluteString);
NSLog(@"path: %@", aLocalURL.path);

产出:

绝对字符串: file:///Users/dennis/Desktop/
Path:/Users/Dennis/Desktop 路径:/用户/Dennis/桌面

所以我们看到 absoluteString仍然知道它的方案,而 path不再有这些信息了。

注意: path是一个文件(目录) URL,作为 医生状态,它的尾部斜杠被去掉了。


现在让我们看看远程 URL。对于这些类型的 URL,大多数人都比较熟悉。我们使用与本地 URL 相同的过程创建它。我们的方案现在是 http://,我们的 pathwww.apple.com/

NSURL *anHTTPURL = [NSURL URLWithString:@"http://www.apple.com/"];
NSLog(@"absolute string: %@", anHTTPURL.absoluteString);
NSLog(@"path: %@", anHTTPURL.path);

产出:

绝对字符串: http://www.apple.com/
路径:/

同样,我们看到绝对字符串仍然知道它的方案,但是 path现在是 /。因此,在使用远程 URL 时,path似乎不是一种合适的方法。

然而,当我们有一个像 http://www.apple.com/index.htmlURL,我们得到了什么

绝对字符串: http://www.apple.com/index.html
路径:/index.html

阅读这些文档也有帮助:

根据 RFC3986,权限(主机名和端口)部分后面的前导斜杠被视为路径的一部分。

所以 path是所有从(包括)在 authority之后的斜杠处开始的东西,在我们的例子中是 www.apple.com


问题2

有没有什么时候一个应该用在另一个上面?

来自 医生: (方法: path)

如果此 URL 对象包含文件 URL (使用 isFileURL 确定) ,则此方法的返回值适合输入到 NSFileManager 或 NSPathUtitility 的方法中。

在我看来,这句话说的 很明显,你应该使用 path时,你与 NSFileManagerNSPathUtilities的工作。


结论:

当您使用 远程网址时,您(通常)使用 absoluteString,否则结果不是您(通常)想要的。
使用 本地网址时,请使用 path

资料来源:
Http://www.ietf.org/rfc/rfc1808.txt
Http://www.ietf.org/rfc/rfc3986.txt
类引用

增加 HAS 的响应—— Apple 文档提到基于 Path 的 URL 在某些方面更简单,但是文件引用 URL 的优点是,如果在应用程序运行时文件被移动或重命名,引用仍然有效。

来自“访问文件和目录”的文档:

”基于路径的 URL 更容易操作、更容易调试,通常是 NSFileManager 等类的首选。文件引用 URL 的一个优点是,在应用程序运行时,它们不像基于路径的 URL 那么脆弱。如果用户在 Finder 中移动文件,任何引用该文件的基于路径的 URL 将立即变为无效,并且必须更新到新路径。但是,只要文件移动到同一磁盘上的另一个位置,它的唯一 ID 就不会改变,任何文件引用 URL 都是有效的。”

Https://developer.apple.com/library/content/documentation/filemanagement/conceptual/filesystemprogrammingguide/accessingfilesanddirectories/accessingfilesanddirectories.html

还有一个注意事项,我只在 Swift 和 URL而不是 NSURL中尝试过:

URL(fileURLWithPath: aPath, relativeTo: URL)

生成一个不完全像远程 URL (如上面的@HAS)而不像文件 URL 的 URL。

例如:

let url0 = URL(fileURLWithPath: "/Foo")
let url1 = URL(fileURLWithPath: "Bar", relativeTo: url0)
print("\(url1.path)")
// Output: "/Bar\n"

(类似于远程 URL 的结果,但不是文件 URL)。

如果我们使用 absoluteString,我们得到:

print("\(url1.absoluteString)")
// Output: "file:///Bar\n"

(与文件 URL 或远程 URL 都不相似)。