Okio's file system is designed to be easy, testable, multiplatform, and efficient.
Reading and writing files is concise yet flexible.
val path = "README.md".toPath() val readmeContent = FileSystem.SYSTEM.read(path) { readUtf8() } val updatedContent = readmeContent.replace("red", "blue") FileSystem.SYSTEM.write(path) { writeUtf8(updatedContent) }
It's easy to swap out the real file system with a fake. This makes tests run faster and more reliably.
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() })
With ForwardingFileSystem
you can easily inject faults to confirm your program is graceful even when the user's disk fills up.
Okio’s Path
class supports Windows-style (like C:\autoexec.bat
) and UNIX-style paths (like /etc/passwd
). It supports manipulating Windows paths on UNIX, and UNIX paths on Windows.
The system FileSystem
abstracts over these platform APIs:
Read and write operations integrate with Okio buffers to reduce the number of system calls.
It exposes high-level operations like atomicMove()
and metadata
to get the OS to do all the work when appropriate.
Okio's implementation is constrained by the capabilities its underlying APIs. This page is an overview of these limitations.
java.io.File
, all treat paths as strings.FileSystem.atomicMove()
fails if the target file already exists.source()
and sink()
cannot access UNIX pipes.NodeJsFileSystem.metadataOrNull()
throws IOException
if the path is invalid. (In the Node.js API there's no mechanism to differentiate between a failure to read a valid path and a rejection of an invalid path.)