1File System 2=========== 3 4Okio's file system is designed to be easy, testable, multiplatform, and efficient. 5 6### Easy 7 8Reading and writing files is concise yet flexible. 9 10```kotlin 11val path = "README.md".toPath() 12 13val readmeContent = FileSystem.SYSTEM.read(path) { 14 readUtf8() 15} 16 17val updatedContent = readmeContent.replace("red", "blue") 18 19FileSystem.SYSTEM.write(path) { 20 writeUtf8(updatedContent) 21} 22``` 23 24 25### Testable 26 27It's easy to swap out the real file system with a fake. This makes tests run faster and more 28reliably. 29 30```kotlin 31val fileSystem = FakeFileSystem() 32val userHome = "/Users/sandy".toPath() 33val gitConfig = userHome / ".gitconfig" 34 35fileSystem.createDirectories(userHome) 36val original = """ 37 |[user] 38 | email = [email protected] 39 |""".trimMargin() 40fileSystem.write(gitConfig) { writeUtf8(original) } 41 42GitConfigFixer(fileSystem).fix(userHome) 43 44val expected = """ 45 |[user] 46 | email = [email protected] 47 |[diff] 48 | renames = true 49 | indentHeuristic = on 50 """.trimIndent() 51assertEquals(expected, fileSystem.read(gitConfig) { readUtf8() }) 52``` 53 54With `ForwardingFileSystem` you can easily inject faults to confirm your program is graceful even 55when the user's disk fills up. 56 57 58### Multiplatform 59 60Okio’s `Path` class supports Windows-style (like `C:\autoexec.bat`) and UNIX-style paths 61(like `/etc/passwd`). It supports manipulating Windows paths on UNIX, and UNIX paths on Windows. 62 63The system `FileSystem` abstracts over these platform APIs: 64 65 * Android API levels <26: [java.io.File](https://developer.android.com/reference/java/io/File) 66 * Java and Android API level 26+: [java.nio.file](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/file/FileSystem.html) 67 * Linux: [man pages](https://www.kernel.org/doc/man-pages/) 68 * UNIX: [stdio.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html) 69 * Windows: [fileapi.h](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/) 70 * Node.js: [file system](https://nodejs.org/api/fs.html) 71 72 73### Efficient 74 75Read and write operations integrate with Okio buffers to reduce the number of system calls. 76 77It exposes high-level operations like `atomicMove()` and `metadata` to get the OS to do all the work 78when appropriate. 79 80 81## Known Issues 82 83 84Okio's implementation is constrained by the capabilities its underlying APIs. This page is an 85overview of these limitations. 86 87 88### All Platforms 89 90 * There are no APIs for file permissions, watches, volume management, memory mapping, or locking. 91 * Paths that cannot be represented as UTF-8 strings are unsupported. The underlying APIs that Okio 92 calls through, including `java.io.File`, all treat paths as strings. 93 94 95### Kotlin/JVM 96 97#### On Android, API level less than 26: 98 99 * Creating and accessing symlinks is unsupported. 100 101 102#### On Windows: 103 104 * `FileSystem.atomicMove()` fails if the target file already exists. 105 106 107### Kotlin/Native 108 109 * FakeFileSystem does not support concurrent use. We are [holding off on this][fake_fs_concurrency] 110 until the upcoming memory model is released. 111 112#### On Windows: 113 114 * Creating and accessing symlinks is unsupported. 115 116 117### Kotlin/JS 118 119 * NodeJsFileSystem's `source()` and `sink()` cannot access UNIX pipes. 120 * Instead of returning null, `NodeJsFileSystem.metadataOrNull()` throws `IOException` if the path 121 is invalid. (In the Node.js API there's no mechanism to differentiate between a failure to read 122 a valid path and a rejection of an invalid path.) 123 124 125[fake_fs_concurrency]: https://github.com/square/okio/issues/950 126