0
# File I/O Operations
1
2
Comprehensive file input/output operations including streams, readers/writers, and high-level convenience methods for text and binary data with charset support and proper resource management.
3
4
## Capabilities
5
6
### Stream Operations
7
8
Create input and output streams for low-level file operations.
9
10
```kotlin { .api }
11
/**
12
* Constructs a new InputStream of this file and returns it as a result.
13
* The options parameter determines how the file is opened.
14
*/
15
fun Path.inputStream(vararg options: OpenOption): InputStream
16
17
/**
18
* Constructs a new OutputStream of this file and returns it as a result.
19
* The options parameter determines how the file is opened.
20
*/
21
fun Path.outputStream(vararg options: OpenOption): OutputStream
22
```
23
24
**Usage Examples:**
25
26
```kotlin
27
import kotlin.io.path.*
28
import java.nio.file.Paths
29
import java.nio.file.StandardOpenOption
30
31
val inputFile = Paths.get("/home/user/data.bin")
32
val outputFile = Paths.get("/home/user/processed.bin")
33
34
// Copy binary data using streams
35
inputFile.inputStream().use { input ->
36
outputFile.outputStream().use { output ->
37
input.copyTo(output)
38
}
39
}
40
41
// Write binary data with specific options
42
val binaryData = byteArrayOf(0x48, 0x65, 0x6C, 0x6C, 0x6F) // "Hello"
43
outputFile.outputStream(StandardOpenOption.CREATE, StandardOpenOption.APPEND).use { output ->
44
output.write(binaryData)
45
}
46
```
47
48
### Reader and Writer Operations
49
50
Create character-based readers and writers with charset support and buffering.
51
52
```kotlin { .api }
53
/**
54
* Returns a new InputStreamReader for reading the content of this file.
55
* @param charset character set to use for reading text, UTF-8 by default
56
* @param options options to determine how the file is opened
57
*/
58
fun Path.reader(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): InputStreamReader
59
60
/**
61
* Returns a new BufferedReader for reading the content of this file.
62
* @param charset character set to use for reading text, UTF-8 by default
63
* @param bufferSize necessary size of the buffer
64
* @param options options to determine how the file is opened
65
*/
66
fun Path.bufferedReader(
67
charset: Charset = Charsets.UTF_8,
68
bufferSize: Int = DEFAULT_BUFFER_SIZE,
69
vararg options: OpenOption
70
): BufferedReader
71
72
/**
73
* Returns a new OutputStreamWriter for writing the content of this file.
74
* @param charset character set to use for writing text, UTF-8 by default
75
* @param options options to determine how the file is opened
76
*/
77
fun Path.writer(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): OutputStreamWriter
78
79
/**
80
* Returns a new BufferedWriter for writing the content of this file.
81
* @param charset character set to use for writing text, UTF-8 by default
82
* @param bufferSize necessary size of the buffer
83
* @param options options to determine how the file is opened
84
*/
85
fun Path.bufferedWriter(
86
charset: Charset = Charsets.UTF_8,
87
bufferSize: Int = DEFAULT_BUFFER_SIZE,
88
vararg options: OpenOption
89
): BufferedWriter
90
```
91
92
**Usage Examples:**
93
94
```kotlin
95
import kotlin.io.path.*
96
import java.nio.file.Paths
97
import java.nio.charset.StandardCharsets
98
99
val textFile = Paths.get("/home/user/document.txt")
100
val outputFile = Paths.get("/home/user/processed.txt")
101
102
// Read with custom charset
103
textFile.reader(StandardCharsets.ISO_8859_1).use { reader ->
104
val content = reader.readText()
105
println("Content: $content")
106
}
107
108
// Write with buffered writer
109
outputFile.bufferedWriter(StandardCharsets.UTF_8, bufferSize = 8192).use { writer ->
110
writer.write("Line 1\n")
111
writer.write("Line 2\n")
112
writer.flush()
113
}
114
115
// Process large files efficiently
116
val largeFile = Paths.get("/home/user/large-text.txt")
117
largeFile.bufferedReader().use { reader ->
118
var lineCount = 0
119
reader.forEachLine { line ->
120
lineCount++
121
if (line.contains("ERROR")) {
122
println("Error found on line $lineCount: $line")
123
}
124
}
125
}
126
```
127
128
### Binary Data Operations
129
130
High-level operations for reading and writing binary data.
131
132
```kotlin { .api }
133
/**
134
* Gets the entire content of this file as a byte array.
135
* It's not recommended to use this function on huge files.
136
*/
137
fun Path.readBytes(): ByteArray
138
139
/**
140
* Writes an array of bytes to this file.
141
* By default, the file will be overwritten if it already exists.
142
*/
143
fun Path.writeBytes(array: ByteArray, vararg options: OpenOption)
144
145
/**
146
* Appends an array of bytes to the content of this file.
147
*/
148
fun Path.appendBytes(array: ByteArray)
149
```
150
151
**Usage Examples:**
152
153
```kotlin
154
import kotlin.io.path.*
155
import java.nio.file.Paths
156
157
val imageFile = Paths.get("/home/user/image.jpg")
158
val backupFile = Paths.get("/home/user/backup/image.jpg")
159
160
// Read entire file as bytes (use carefully with large files)
161
val imageData = imageFile.readBytes()
162
println("Image size: ${imageData.size} bytes")
163
164
// Write bytes to new file
165
backupFile.createParentDirectories()
166
backupFile.writeBytes(imageData)
167
168
// Append binary data
169
val additionalData = byteArrayOf(0xFF, 0xFE, 0xFD)
170
backupFile.appendBytes(additionalData)
171
172
// Working with smaller binary files
173
val configData = "key=value\n".toByteArray()
174
val configFile = Paths.get("/tmp/config.dat")
175
configFile.writeBytes(configData)
176
```
177
178
### Text Operations
179
180
High-level operations for reading and writing text with charset support.
181
182
```kotlin { .api }
183
/**
184
* Gets the entire content of this file as a String using UTF-8 or the specified charset.
185
* It's not recommended to use this function on huge files.
186
*/
187
fun Path.readText(charset: Charset = Charsets.UTF_8): String
188
189
/**
190
* Sets the content of this file as text encoded using UTF-8 or the specified charset.
191
* By default, the file will be overwritten if it already exists.
192
*/
193
fun Path.writeText(text: CharSequence, charset: Charset = Charsets.UTF_8, vararg options: OpenOption)
194
195
/**
196
* Appends text to the content of this file using UTF-8 or the specified charset.
197
*/
198
fun Path.appendText(text: CharSequence, charset: Charset = Charsets.UTF_8)
199
```
200
201
**Usage Examples:**
202
203
```kotlin
204
import kotlin.io.path.*
205
import java.nio.file.Paths
206
import java.nio.charset.StandardCharsets
207
208
val textFile = Paths.get("/home/user/notes.txt")
209
210
// Write text content
211
val notes = """
212
Meeting Notes - ${java.time.LocalDate.now()}
213
==========================================
214
215
- Discussed project timeline
216
- Reviewed code architecture
217
- Planned next sprint
218
""".trimIndent()
219
220
textFile.writeText(notes)
221
222
// Read text content
223
val content = textFile.readText()
224
println("File content:\n$content")
225
226
// Append additional text
227
textFile.appendText("\n\nAction Items:\n- Update documentation\n- Fix unit tests")
228
229
// Work with different charsets
230
val europeanFile = Paths.get("/home/user/european-text.txt")
231
val europeanText = "Café, naïve, résumé"
232
europeanFile.writeText(europeanText, StandardCharsets.ISO_8859_1)
233
234
val readEuropeanText = europeanFile.readText(StandardCharsets.ISO_8859_1)
235
println("European text: $readEuropeanText")
236
```
237
238
### Line-Based Operations
239
240
Operations for reading and writing files line by line with memory-efficient processing.
241
242
```kotlin { .api }
243
/**
244
* Reads the file content as a list of lines.
245
* It's not recommended to use this function on huge files.
246
*/
247
fun Path.readLines(charset: Charset = Charsets.UTF_8): List<String>
248
249
/**
250
* Writes the specified collection of char sequences to a file terminating each one with the platform's line separator.
251
* By default, the file will be overwritten if it already exists.
252
*/
253
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = Charsets.UTF_8, vararg options: OpenOption): Path
254
255
/**
256
* Writes the specified sequence of char sequences to a file terminating each one with the platform's line separator.
257
*/
258
fun Path.writeLines(lines: Sequence<CharSequence>, charset: Charset = Charsets.UTF_8, vararg options: OpenOption): Path
259
260
/**
261
* Appends the specified collection of char sequences to a file terminating each one with the platform's line separator.
262
*/
263
fun Path.appendLines(lines: Iterable<CharSequence>, charset: Charset = Charsets.UTF_8): Path
264
265
/**
266
* Appends the specified sequence of char sequences to a file terminating each one with the platform's line separator.
267
*/
268
fun Path.appendLines(lines: Sequence<CharSequence>, charset: Charset = Charsets.UTF_8): Path
269
270
/**
271
* Reads this file line by line using the specified charset and calls action for each line.
272
* You may use this function on huge files.
273
*/
274
fun Path.forEachLine(charset: Charset = Charsets.UTF_8, action: (line: String) -> Unit)
275
276
/**
277
* Calls the block callback giving it a sequence of all the lines in this file and closes the reader once
278
* the processing is complete.
279
*/
280
fun <T> Path.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence<String>) -> T): T
281
```
282
283
**Usage Examples:**
284
285
```kotlin
286
import kotlin.io.path.*
287
import java.nio.file.Paths
288
289
val csvFile = Paths.get("/home/user/data.csv")
290
val outputFile = Paths.get("/home/user/processed.csv")
291
292
// Write lines from collection
293
val headers = listOf("Name", "Age", "City")
294
val data = listOf(
295
"Alice,25,New York",
296
"Bob,30,San Francisco",
297
"Charlie,28,Chicago"
298
)
299
300
csvFile.writeLines(headers + data)
301
302
// Read all lines at once (use carefully with large files)
303
val allLines = csvFile.readLines()
304
println("Total lines: ${allLines.size}")
305
306
// Process lines efficiently for large files
307
csvFile.forEachLine { line ->
308
if (line.startsWith("Error:")) {
309
println("Found error: $line")
310
}
311
}
312
313
// Use lines with sequence for memory-efficient processing
314
val errorCount = csvFile.useLines { lines ->
315
lines.count { it.contains("ERROR") }
316
}
317
println("Total errors: $errorCount")
318
319
// Transform and write lines
320
val transformedLines = csvFile.useLines { lines ->
321
lines.drop(1) // Skip header
322
.map { line ->
323
val parts = line.split(",")
324
if (parts.size >= 3) {
325
"${parts[0].uppercase()},${parts[1]},${parts[2].uppercase()}"
326
} else {
327
line
328
}
329
}
330
.toList()
331
}
332
333
outputFile.writeLines(listOf("NAME,AGE,CITY") + transformedLines)
334
335
// Append processed results
336
val summary = listOf(
337
"",
338
"Summary:",
339
"Total records: ${transformedLines.size}",
340
"Processed on: ${java.time.LocalDateTime.now()}"
341
)
342
outputFile.appendLines(summary)
343
```
344
345
### Advanced I/O Patterns
346
347
Combining different I/O operations for complex file processing scenarios.
348
349
**Usage Examples:**
350
351
```kotlin
352
import kotlin.io.path.*
353
import java.nio.file.Paths
354
import java.nio.file.StandardOpenOption
355
356
val logFile = Paths.get("/var/log/application.log")
357
val archiveFile = Paths.get("/var/log/archive/application-${java.time.LocalDate.now()}.log")
358
359
// Rotate log file
360
if (logFile.exists() && logFile.fileSize() > 10_000_000) { // 10MB
361
// Copy current log to archive
362
archiveFile.createParentDirectories()
363
logFile.copyTo(archiveFile, overwrite = true)
364
365
// Clear current log
366
logFile.writeText("")
367
}
368
369
// Process configuration file with validation
370
val configFile = Paths.get("/etc/myapp/config.properties")
371
val backupConfigFile = Paths.get("/etc/myapp/config.properties.backup")
372
373
if (configFile.exists()) {
374
// Create backup
375
configFile.copyTo(backupConfigFile, overwrite = true)
376
377
// Read and validate configuration
378
val config = mutableMapOf<String, String>()
379
380
configFile.forEachLine { line ->
381
val trimmed = line.trim()
382
if (trimmed.isNotEmpty() && !trimmed.startsWith("#")) {
383
val parts = trimmed.split("=", limit = 2)
384
if (parts.size == 2) {
385
config[parts[0].trim()] = parts[1].trim()
386
}
387
}
388
}
389
390
// Write validated configuration
391
val validatedLines = config.map { (key, value) -> "$key=$value" }
392
configFile.writeLines(validatedLines)
393
}
394
395
// Batch process multiple files
396
val dataDir = Paths.get("/home/user/data")
397
val processedDir = Paths.get("/home/user/processed")
398
399
processedDir.createDirectories()
400
401
dataDir.listDirectoryEntries("*.txt").forEach { inputFile ->
402
val outputFile = processedDir / inputFile.name
403
404
inputFile.useLines { lines ->
405
val processedLines = lines
406
.filter { it.isNotBlank() }
407
.map { it.trim().uppercase() }
408
.toList()
409
410
outputFile.writeLines(processedLines)
411
}
412
413
println("Processed: ${inputFile.name}")
414
}
415
```