File System¶
Okio’s file system is designed to be easy, testable, multiplatform, and efficient.
Easy¶
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)
}
Testable¶
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.
Multiplatform¶
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:
- Android API levels <26: java.io.File
- Java and Android API level 26+: java.nio.file
- Linux: man pages
- UNIX: stdio.h
- Windows: fileapi.h
- Node.js: file system
Efficient¶
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.
Known Issues¶
Okio’s implementation is constrained by the capabilities its underlying APIs. This page is an overview of these limitations.
All Platforms¶
- There are no APIs for file permissions, watches, volume management, memory mapping, or locking.
- Paths that cannot be represented as UTF-8 strings are unsupported. The underlying APIs that Okio
calls through, including
java.io.File
, all treat paths as strings.
Kotlin/JVM¶
On Android, API level less than 26:¶
- Creating and accessing symlinks is unsupported.
On Windows:¶
FileSystem.atomicMove()
fails if the target file already exists.
Kotlin/Native¶
- FakeFileSystem does not support concurrent use. We are holding off on this until the upcoming memory model is released.
On Windows:¶
- Creating and accessing symlinks is unsupported.
Kotlin/JS¶
- NodeJsFileSystem’s
source()
andsink()
cannot access UNIX pipes. - Instead of returning null,
NodeJsFileSystem.metadataOrNull()
throwsIOException
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.)