-
Notifications
You must be signed in to change notification settings - Fork 5.9k
/
Copy pathReadWrite.kt
151 lines (132 loc) · 5.06 KB
/
ReadWrite.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
* 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<String> {
val result = arrayListOf<String>()
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 <T> Reader.useLines(block: (Sequence<String>) -> 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<String> = LinesSequence(this).constrainOnce()
private class LinesSequence(private val reader: BufferedReader) : Sequence<String> {
override public fun iterator(): Iterator<String> {
return object : Iterator<String> {
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() }