【问题标题】:Swift: How to expand a tilde in a path StringSwift:如何在路径字符串中扩展波浪号
【发布时间】:2016-11-05 11:56:03
【问题描述】:

如何在 Swift 中使用波浪号扩展路径字符串?我有一个类似"~/Desktop" 的字符串,我想将此路径与NSFileManager 方法一起使用,这需要将波浪号扩展为"/Users/<myuser>/Desktop"

(这个带有明确问题陈述的问题尚不存在,这应该很容易找到。一些类似但不令人满意的问题是Can not make path to the file in SwiftSimple way to read local file using Swift?Tilde-based Paths in Objective-C

【问题讨论】:

    标签: swift path nsfilemanager home-directory tilde-expansion


    【解决方案1】:

    波浪号扩展

    斯威夫特 1

    "~/Desktop".stringByExpandingTildeInPath
    

    斯威夫特 2

    NSString(string: "~/Desktop").stringByExpandingTildeInPath
    

    斯威夫特 3

    NSString(string: "~/Desktop").expandingTildeInPath
    

    主目录

    此外,您还可以像这样获取主目录(返回 String/String?):

    NSHomeDirectory()
    NSHomeDirectoryForUser("<User>")
    

    在 Swift 3 和 OS X 10.12 中也可以使用它(返回 URL/URL?):

    FileManager.default().homeDirectoryForCurrentUser
    FileManager.default().homeDirectory(forUser: "<User>")
    

    编辑:在 Swift 3.1 中,这已更改为 FileManager.default.homeDirectoryForCurrentUser

    【讨论】:

    • +,尤其是对于自我回答
    • FileManager.default() 在 Swift 3.1 中只是 FileManager.default
    • 因此,Swift 3.1 "~/Desktop" 等价物可以是 let homeDir = FileManager.default.homeDirectoryForCurrentUser 后跟 let desktopDir = homeDir.appendingPathComponent("Desktop", isDirectory: true)
    • 在 URL 中使用路径时(如 URL(fileURLWithPath: "~/Desktop").path),这将导致 "/private/tmp/~/Desktop"
    • @NickK9 我不再使用 Swift,因此无法提供有关此的更新。您可以更新我的答案以提供更新
    【解决方案2】:

    返回字符串:

    func expandingTildeInPath(_ path: String) -> String {
        return path.replacingOccurrences(of: "~", with: FileManager.default.homeDirectoryForCurrentUser.path)
    }
    

    返回网址:

    func expandingTildeInPath(_ path: String) -> URL {
        return URL(fileURLWithPath: path.replacingOccurrences(of: "~", with: FileManager.default.homeDirectoryForCurrentUser.path))
    }
    

    如果操作系统低于10.12,更换

    FileManager.default.homeDirectoryForCurrentUser
    

    URL(fileURLWithPath: NSHomeDirectory()
    

    【讨论】:

      【解决方案3】:

      这是一个不依赖于NSString 类并适用于 Swift 4 的解决方案:

      func absURL ( _ path: String ) -> URL {
          guard path != "~" else {
              return FileManager.default.homeDirectoryForCurrentUser
          }
          guard path.hasPrefix("~/") else { return URL(fileURLWithPath: path)  }
      
          var relativePath = path
          relativePath.removeFirst(2)
          return URL(fileURLWithPath: relativePath,
              relativeTo: FileManager.default.homeDirectoryForCurrentUser
          )
      }
      
      func absPath ( _ path: String ) -> String {
          return absURL(path).path
      }
      

      测试代码:

      print("Path: \(absPath("~"))")
      print("Path: \(absPath("/tmp/text.txt"))")
      print("Path: \(absPath("~/Documents/text.txt"))")
      

      将代码拆分为两种方法的原因是,现在您在处理文件和文件夹时更希望使用 URL,而不是字符串路径(所有新的 API 都使用 URL 作为路径)。

      顺便说一句,如果您只想知道~/Desktop~/Documents 和类似文件夹的绝对路径,还有一种更简单的方法:

      let desktop = FileManager.default.urls(
          for: .desktopDirectory, in: .userDomainMask
      )[0]
      print("Desktop: \(desktop.path)")
      
      let documents = FileManager.default.urls(
          for: .documentDirectory, in: .userDomainMask
      )[0]
      print("Documents: \(documents.path)")
      

      【讨论】:

      • @Alexander 在 NSURL 方面 ~ 是有问题的,因为所有目录都必须以 / 结尾作为它们是目录的指示符(否则使用这样的 URL 作为 baseURL 会产生不良影响)和不是文件,例如file:///var/xxx,xxx是什么?你不能知道。在没有进一步知识的情况下,NSURL 将假定它是一个文件,但在 file:///var/xxx/ 的情况下,它知道 xxx 是一个目录,并且尾随 / 对于 Mac 上的所有文件 API(包括 BSD 和 Cocoa)都是合法的。如果您只需要解析 ~,请调用 FileManager.default.homeDirectoryForCurrentUser 并将结果设为 URL。
      • 啊,有道理。这是一个很有用的约定
      • @Alexander 我将更新代码并将普通的~ 视为特殊情况。我认为这比尝试找到始终正确运行的解决方案要容易。
      • NSURL.standardizingPath 应该能够正确处理所有这些,但由于某种原因,没有导入到URL
      【解决方案4】:

      Swift 4 扩展

      public extension String {
      
          public var expandingTildeInPath: String {
              return NSString(string: self).expandingTildeInPath
          }
      
      }
      

      【讨论】:

      • 注意 - 如果从沙盒应用程序中使用它,您必须非常小心。你可能会走错路……
      猜你喜欢
      • 2017-02-28
      • 2011-08-10
      • 2011-06-06
      • 2013-03-29
      • 1970-01-01
      • 2020-03-13
      • 2011-03-05
      相关资源
      最近更新 更多