跳到内容

文件系统

Okio 的文件系统被设计为易用、可测试、多平台且高效。

易用

读写文件简洁而灵活。

val path = "README.md".toPath()

val readmeContent = FileSystem.SYSTEM.read(path) {
  readUtf8()
}

val updatedContent = readmeContent.replace("red", "blue")

FileSystem.SYSTEM.write(path) {
  writeUtf8(updatedContent)
}

可测试

可以轻松地用模拟文件系统替换真实文件系统。这使得测试运行更快、更可靠。

val fileSystem = FakeFileSystem()
val userHome = "/Users/sandy".toPath()
val gitConfig = userHome / ".gitconfig"

fileSystem.createDirectories(userHome)
val original = """
    |[user]
    |  email = sandy@example.com
    |""".trimMargin()
fileSystem.write(gitConfig) { writeUtf8(original) }

GitConfigFixer(fileSystem).fix(userHome)

val expected = """
  |[user]
  |  email = sandy@example.com
  |[diff]
  |  renames = true
  |  indentHeuristic = on
  """.trimIndent()
assertEquals(expected, fileSystem.read(gitConfig) { readUtf8() })

使用 ForwardingFileSystem,你可以轻松注入故障,以确认即使在用户磁盘满时,你的程序也能优雅地运行。

多平台

Okio 的 Path 类支持 Windows 风格(如 C:\autoexec.bat)和 UNIX 风格的路径(如 /etc/passwd)。它支持在 UNIX 上操作 Windows 路径,以及在 Windows 上操作 UNIX 路径。

系统 FileSystem 抽象了这些平台 API:

高效

读写操作与 Okio 缓冲区集成,以减少系统调用的次数。

它暴露了诸如 atomicMove()metadata 等高级操作,以便在适当时候让操作系统完成所有工作。

已知问题

Okio 的实现受到其底层 API 功能的限制。本页概述了这些限制。

所有平台

  • 没有用于文件权限、监视、卷管理、内存映射或锁定的 API。
  • 不支持不能表示为 UTF-8 字符串的路径。Okio 调用的底层 API,包括 java.io.File,都将路径视为字符串。

Kotlin/JVM

在 Android 上,API 级别低于 26:

  • 不支持创建和访问符号链接。

在 Windows 上:

  • 如果目标文件已存在,FileSystem.atomicMove() 将失败。

Kotlin/Native

  • FakeFileSystem 不支持并发使用。我们正在等待即将发布的内存模型,在此之前暂缓处理此问题。

在 Windows 上:

  • 不支持创建和访问符号链接。

Kotlin/JS

  • NodeJsFileSystem 的 source()sink() 无法访问 UNIX 管道。
  • NodeJsFileSystem.metadataOrNull() 在路径无效时会抛出 IOException,而不是返回 null。(在 Node.js API 中,无法区分读取有效路径失败和拒绝无效路径。)