70

我在 SO 上看到了很多关于在NSURL和之间转换的问题NSString。它们都涉及使用NSString *path = [myURL absoluteString];NSString *path = [myURL path];这些方法之间的实际区别是什么? 有没有时候应该使用一个而不是另一个? 我尝试咨询Apple Docs,但我发现它没有多大帮助。

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

4

3 回答 3

157

问题一:

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

让我们分析一下这 6 行代码 - 3 行用于本地,3 行用于 http URL - 并稍微玩弄一下它们。

NSURL让我们使用该file://方案创建一个。如果您问自己为什么有 3 个/file:那么您应该记住方案的完整 URL 存在(以及绝对或相对路径(您可以在第 3 页的 RFC 1808file://中找到有关创建 URL 的更多信息)。我们使用以绝对路径开头有了 a ,我们最终得到。////

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

输出:

绝对字符串:file:///Users/dennis/Desktop/
路径:/Users/dennis/Desktop

所以我们看到它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现在是/. 因此path,在使用远程 URL 时似乎不是一种合适的方式。

但是,当我们得到一个赞URLhttp://www.apple.com/index.html

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

阅读文档在这里也有帮助:

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

因此,在我们的例子中path,一切都从斜线开始(包括) 。authoritywww.apple.com


问题2

有没有时候应该使用一个而不是另一个?

来自文档:(方法path:)

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

在我看来,这句话清楚地表明你应该在使用orpath时使用。NSFileManagerNSPathUtilities


结论:

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

来源:
http ://www.ietf.org/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc3986.txt
NSURL 类参考

于 2013-04-23T20:27:47.073 回答
0

还有一点需要注意,我只为 Swift 而URL不是NSURL. relativeTo网址格式:

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 不同)。

于 2020-04-18T18:15:52.567 回答
0

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

从“访问文件和目录”的文档中:

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

https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html

于 2018-01-13T23:40:00.580 回答