kotlin.io.ReadWrite.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:JvmName("TextStreamsKt")
package kotlin.io
import java.io.*
import java.nio.charset.Charset
import java.net.URL
import java.util.NoSuchElementException
import kotlin.internal.*
/** Returns a buffered reader wrapping this Reader, or this Reader itself if it is already buffered. */
@kotlin.internal.InlineOnly
public inline fun Reader.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): BufferedReader =
if (this is BufferedReader) this else BufferedReader(this, bufferSize)
/** Returns a buffered writer wrapping this Writer, or this Writer itself if it is already buffered. */
@kotlin.internal.InlineOnly
public inline fun Writer.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): BufferedWriter =
if (this is BufferedWriter) this else BufferedWriter(this, bufferSize)
/**
* Iterates through each line of this reader, calls [action] for each line read
* and closes the [Reader] when it's completed.
*
* @param action function to process file lines.
*/
public fun Reader.forEachLine(action: (String) -> Unit): Unit = useLines { it.forEach(action) }
/**
* Reads this reader content as a list of lines.
*
* Do not use this function for huge files.
*/
public fun Reader.readLines(): List {
val result = arrayListOf()
forEachLine { result.add(it) }
return result
}
/**
* Calls the [block] callback giving it a sequence of all the lines in this file and closes the reader once
* the processing is complete.
* @return the value returned by [block].
*/
@RequireKotlin("1.2", versionKind = RequireKotlinVersionKind.COMPILER_VERSION, message = "Requires newer compiler version to be inlined correctly.")
public inline fun Reader.useLines(block: (Sequence) -> T): T =
buffered().use { block(it.lineSequence()) }
/** Creates a new reader for the string. */
@kotlin.internal.InlineOnly
public inline fun String.reader(): StringReader = StringReader(this)
/**
* Returns a sequence of corresponding file lines.
*
* *Note*: the caller must close the underlying `BufferedReader`
* when the iteration is finished; as the user may not complete the iteration loop (e.g. using a method like find() or any() on the iterator
* may terminate the iteration early.
*
* We suggest you try the method [useLines] instead which closes the stream when the processing is complete.
*
* @return a sequence of corresponding file lines. The sequence returned can be iterated only once.
*/
public fun BufferedReader.lineSequence(): Sequence = LinesSequence(this).constrainOnce()
private class LinesSequence(private val reader: BufferedReader) : Sequence {
override public fun iterator(): Iterator {
return object : Iterator {
private var nextValue: String? = null
private var done = false
override public fun hasNext(): Boolean {
if (nextValue == null && !done) {
nextValue = reader.readLine()
if (nextValue == null) done = true
}
return nextValue != null
}
override public fun next(): String {
if (!hasNext()) {
throw NoSuchElementException()
}
val answer = nextValue
nextValue = null
return answer!!
}
}
}
}
/**
* Reads this reader completely as a String.
*
* *Note*: It is the caller's responsibility to close this reader.
*
* @return the string with corresponding file content.
*/
public fun Reader.readText(): String {
val buffer = StringWriter()
copyTo(buffer)
return buffer.toString()
}
/**
* Copies this reader to the given [out] writer, returning the number of characters copied.
*
* **Note** it is the caller's responsibility to close both of these resources.
*
* @param out writer to write to.
* @param bufferSize size of character buffer to use in process.
* @return number of characters copied.
*/
public fun Reader.copyTo(out: Writer, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long {
var charsCopied: Long = 0
val buffer = CharArray(bufferSize)
var chars = read(buffer)
while (chars >= 0) {
out.write(buffer, 0, chars)
charsCopied += chars
chars = read(buffer)
}
return charsCopied
}
/**
* Reads the entire content of this URL as a String using UTF-8 or the specified [charset].
*
* This method is not recommended on huge files.
*
* @param charset a character set to use.
* @return a string with this URL entire content.
*/
@kotlin.internal.InlineOnly
public inline fun URL.readText(charset: Charset = Charsets.UTF_8): String = readBytes().toString(charset)
/**
* Reads the entire content of the URL as byte array.
*
* This method is not recommended on huge files.
*
* @return a byte array with this URL entire content.
*/
public fun URL.readBytes(): ByteArray = openStream().use { it.readBytes() }