Skip to content

Commit

Permalink
Document the file system (#1056)
Browse files Browse the repository at this point in the history
  • Loading branch information
swankjesse authored Oct 27, 2021
1 parent c9388b3 commit 6565389
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 0 deletions.
125 changes: 125 additions & 0 deletions docs/file_system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
File System
===========

Okio's file system is designed to be easy, testable, multiplatform, and efficient.

### Easy

Reading and writing files is concise yet flexible.

```kotlin
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.

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

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

GitConfigFixer(fileSystem).fix(userHome)

val expected = """
|[user]
| email = [email protected]
|[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](https://developer.android.com/reference/java/io/File)
* 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)
* Linux: [man pages](https://www.kernel.org/doc/man-pages/)
* UNIX: [stdio.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html)
* Windows: [fileapi.h](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/)
* Node.js: [file system](https://nodejs.org/api/fs.html)


### 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][fake_fs_concurrency]
until the upcoming memory model is released.

#### On Windows:

* Creating and accessing symlinks is unsupported.


### Kotlin/JS

* NodeJsFileSystem's `source()` and `sink()` cannot access UNIX pipes.
* Instead of returning null, `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.)


[fake_fs_concurrency]: https://github.com/square/okio/issues/950
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ nav:
- '2.x API': 2.x/okio/okio/index.html
- '1.x API ⏏': https://square.github.io/okio/1.x/okio/
- 'Change Log': changelog.md
- 'File System': file_system.md
- 'Multiplatform': multiplatform.md
- 'Contributing': contributing.md
- 'Code of Conduct': code_of_conduct.md
Expand Down

0 comments on commit 6565389

Please sign in to comment.