Revise functions in PathReadWrite

- 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 commit is contained in:
Ilya Gorbunov
2020-10-15 02:57:09 +03:00
parent a43cc0d1f9
commit fe098ec821
3 changed files with 34 additions and 20 deletions
@@ -26,7 +26,7 @@ import java.nio.file.StandardOpenOption
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.reader(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): InputStreamReader {
return inputStream(*options).reader(charset)
return InputStreamReader(Files.newInputStream(this, *options), charset)
}
/**
@@ -44,7 +44,12 @@ public inline fun Path.bufferedReader(
bufferSize: Int = DEFAULT_BUFFER_SIZE,
vararg options: OpenOption
): BufferedReader {
return reader(charset, *options).buffered(bufferSize)
return BufferedReader(
InputStreamReader(
Files.newInputStream(this, *options),
charset
),
bufferSize)
}
/**
@@ -57,7 +62,7 @@ public inline fun Path.bufferedReader(
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.writer(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): OutputStreamWriter {
return outputStream(*options).writer(charset)
return OutputStreamWriter(Files.newOutputStream(this, *options), charset)
}
/**
@@ -75,13 +80,19 @@ public inline fun Path.bufferedWriter(
bufferSize: Int = DEFAULT_BUFFER_SIZE,
vararg options: OpenOption
): BufferedWriter {
return writer(charset, *options).buffered(bufferSize)
return BufferedWriter(
OutputStreamWriter(
Files.newOutputStream(this, *options),
charset),
bufferSize)
}
/**
* Gets the entire content of this file as a byte array.
*
* This method is not recommended on huge files. It has an internal limitation of 2 GB byte array size.
* It's not recommended to use this function on huge files.
* It has an internal limitation of approximately 2 GB byte array size.
* For reading large files or files of unknown size, open an [InputStream][Path.inputStream] and read blocks sequentially.
*
* @return the entire content of this file as a byte array.
*/
@@ -123,16 +134,16 @@ public inline fun Path.appendBytes(array: ByteArray) {
/**
* Gets the entire content of this file as a String using UTF-8 or the specified [charset].
*
* This method is not recommended on huge files. It has an internal limitation of 2 GB file size.
* It's not recommended to use this function on huge files.
* For reading large files or files of unknown size, open a [Reader][Path.reader] and read blocks of text sequentially.
*
* @param charset character set to use for reading text, UTF-8 by default.
* @return the entire content of this file as a String.
*/
@SinceKotlin("1.4")
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
public fun Path.readText(charset: Charset = Charsets.UTF_8): String =
reader(charset).use { it.readText() }
/**
* Sets the content of this file as [text] encoded using UTF-8 or the specified [charset].
@@ -146,8 +157,8 @@ public inline fun Path.readText(charset: Charset = Charsets.UTF_8): String =
*/
@SinceKotlin("1.4")
@ExperimentalPathApi
public fun Path.writeText(text: String, charset: Charset = Charsets.UTF_8, vararg options: OpenOption): Unit {
writeBytes(text.toByteArray(charset), *options)
public fun Path.writeText(text: String, charset: Charset = Charsets.UTF_8, vararg options: OpenOption) {
Files.newOutputStream(this, *options).writer(charset).use { it.write(text) }
}
/**
@@ -158,8 +169,8 @@ public fun Path.writeText(text: String, charset: Charset = Charsets.UTF_8, varar
*/
@SinceKotlin("1.4")
@ExperimentalPathApi
public fun Path.appendText(text: String, charset: Charset = Charsets.UTF_8): Unit {
writeText(text, charset, StandardOpenOption.APPEND)
public fun Path.appendText(text: String, charset: Charset = Charsets.UTF_8) {
Files.newOutputStream(this, StandardOpenOption.APPEND).writer(charset).use { it.write(text) }
}
/**
@@ -168,15 +179,15 @@ public fun Path.appendText(text: String, charset: Charset = Charsets.UTF_8): Uni
*
* You may use this function on huge files.
*
* @param options options to determine how the file is opened.
* @param charset character set to use for reading text, UTF-8 by default.
* @param action function to process file lines.
*/
@SinceKotlin("1.4")
@ExperimentalPathApi
public fun Path.forEachLine(charset: Charset = Charsets.UTF_8, vararg options: OpenOption, action: (line: String) -> Unit): Unit {
// Note: close is called at forEachLine
bufferedReader(charset, options = options).forEachLine(action)
@kotlin.internal.InlineOnly
public inline fun Path.forEachLine(charset: Charset = Charsets.UTF_8, action: (line: String) -> Unit): Unit {
// cannot use non-inline forEachLine
Files.newBufferedReader(this, charset).useLines { it.forEach(action) }
}
/**
@@ -210,7 +221,8 @@ public inline fun Path.outputStream(vararg options: OpenOption): OutputStream {
/**
* Reads the file content as a list of lines.
*
* Do not use this function for huge files.
* It's not recommended to use this function on huge files.
* For reading lines of a large file or a file of unknown size, use [Path.forEachLine] or [Path.useLines].
*
* @param charset character set to use for reading text, UTF-8 by default.
* @return list of file lines.
@@ -233,7 +245,7 @@ public inline fun Path.readLines(charset: Charset = Charsets.UTF_8): List<String
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun <T> Path.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence<String>) -> T): T {
return bufferedReader(charset).use { block(it.lineSequence()) }
return Files.newBufferedReader(this, charset).use { block(it.lineSequence()) }
}
/**
@@ -35,7 +35,7 @@ class PathReadWriteTest {
writer.close()
val list = ArrayList<String>()
file.forEachLine(charset = Charsets.UTF_8, options = arrayOf(StandardOpenOption.READ)) {
file.forEachLine(charset = Charsets.UTF_8) {
list.add(it)
}
assertEquals(listOf("Hello", "World"), list)
@@ -11,6 +11,8 @@ public final class kotlin/io/path/PathsKt {
public static final fun getNameWithoutExtension (Ljava/nio/file/Path;)Ljava/lang/String;
public static final fun listDirectoryEntries (Ljava/nio/file/Path;Ljava/lang/String;)Ljava/util/List;
public static synthetic fun listDirectoryEntries$default (Ljava/nio/file/Path;Ljava/lang/String;ILjava/lang/Object;)Ljava/util/List;
public static final fun readText (Ljava/nio/file/Path;Ljava/nio/charset/Charset;)Ljava/lang/String;
public static synthetic fun readText$default (Ljava/nio/file/Path;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
public static final fun relativeTo (Ljava/nio/file/Path;Ljava/nio/file/Path;)Ljava/nio/file/Path;
public static final fun relativeToOrNull (Ljava/nio/file/Path;Ljava/nio/file/Path;)Ljava/nio/file/Path;
public static final fun relativeToOrSelf (Ljava/nio/file/Path;Ljava/nio/file/Path;)Ljava/nio/file/Path;