- Adjust implementations to avoid excessive vararg copies
- Remove options from forEachLine, it doesn't make much sense and
isn't consistent with the other read* functions.
- Revise inlineness of functions in PathReadWrite
- Compact implementations of those that are remained inline.
- Clarify docs of functions for reading the entire file
#KT-19192
This PR adds most extensions on `java.io.File` in `kotlin.io` to `java.nio.Path`. This includes extensions from `FileReadWrite.kt`, `Utils.kt`, and `FileTreeWalk.kt`.
I attempted to keep the implementations, documentation, and tests as similar as possible to the existing implementations.
I am happy to add, remove, or move to separate PRs any of the functions of this PR.
### `File` extensions that were not added to `Path`
##### `createTempDir`, `createTempFile`
These functions have no `File` parameters, so can't be overloaded. Equivalents exist as `Files.createTempFile()` and `Files.createTempDirectory()`.
##### `startsWith`, `endsWith`, `normalize`, `resolve`, `resolveSibling`
These exist as member functions on `Path`
##### `relativeTo`, `relativeToOrNull`, `relativeToOrSelf`, `toRelativeString`, `toRelativeStringOrNull`
This functionality exists as the `Path.relativize` member function, which is equivalent to `relativeTo`, but with the receiver and parameter flipped. `foo.relativeTo(bar)` is equivalent to `bar.relativize(foo)`. We could potentially add a `relativizeOrNull` extension to make that pattern simpler.
##### `isRooted`
`Path` has a `root` method, so `isRooted` is equivalent to `root != null`
### New extensions
All of the simple boolean attribute checks from `java.nio.Files` were added as extensions on `Path`. These extensions are used commonly enough that it seems worth supporting them. This functionality for `File` is implemented as member methods.
The following `Path` extensions were added:
- `exists`
- `isDirectory`
- `isExecutable`
- `isFile`
- `isHidden`
- `isReadable`
- `isSameFile`
- `isSymbolicLink`
- `isWritable`
Some of these extensions take options that are forwarded to their `Files` method, so all of the extensions were implemented as functions rather than properties for consistency.
Additionally, `Path.listFiles` was added to match the `File.listFiles` method. One motivation for its addition was that it's used several times in the implementation of other file extensions. The way to list directory contents with `java.nio` is via `Files.newDirectoryStream()`, which returns an iterable object that must be closed to avoid leaking resources. It's difficult to use correctly with functions like `map` and `filter`, so this extension was added as a simpler, less error-prone alternative.
### Other changes
I added overloads of several of the read-write that take `OpenOptions` to expose the greater control that `java.nio` introduces. For example, you can use `printWriter(APPEND)` to create a `PrintWriter` that doesn't delete the contents of an existing file.
All the new extensions throw exceptions (such as `NoSuchFileException`) from `java.nio` rather than the copies from `kotlin.io`. The `kotlin.io` copies take `File` objects as parameters, and so aren't compatible with `Path`s.
### Address review comments
- Move varargs parameters to the last position
- Remove PathTreeWalk
#KT-19192