0
# Async Byte Channels
1
2
Core asynchronous I/O functionality providing single-reader/single-writer channels for non-blocking byte operations with coroutine integration.
3
4
## Capabilities
5
6
### ByteReadChannel Interface
7
8
Single-reader asynchronous byte channel for reading sequences of bytes with coroutine support.
9
10
```kotlin { .api }
11
/**
12
* Channel for asynchronous reading of sequences of bytes.
13
* This is a single-reader channel where operations cannot be invoked concurrently.
14
*/
15
interface ByteReadChannel {
16
/** Number of bytes available for reading without suspension */
17
val availableForRead: Int
18
19
/** True if channel is closed and no remaining bytes are available */
20
val isClosedForRead: Boolean
21
22
/** True if channel is closed for writing */
23
val isClosedForWrite: Boolean
24
25
/** Closure exception or null if closed successfully or not yet closed */
26
val closedCause: Throwable?
27
28
/** Total number of bytes read from the channel */
29
val totalBytesRead: Long
30
31
/**
32
* Reads available bytes to dst buffer, returns immediately or suspends if no bytes available
33
* @param dst destination byte array
34
* @param offset starting position in dst array
35
* @param length maximum number of bytes to read
36
* @return number of bytes read or -1 if channel is closed
37
*/
38
suspend fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int
39
40
/**
41
* Reads exactly length bytes to dst buffer or fails if channel is closed
42
* @param dst destination byte array
43
* @param offset starting position in dst array
44
* @param length exact number of bytes to read
45
*/
46
suspend fun readFully(dst: ByteArray, offset: Int, length: Int)
47
48
/** Read a single byte, suspending if necessary */
49
suspend fun readByte(): Byte
50
51
/** Read a 16-bit short value in big-endian byte order */
52
suspend fun readShort(): Short
53
54
/** Read a 32-bit int value in big-endian byte order */
55
suspend fun readInt(): Int
56
57
/** Read a 64-bit long value in big-endian byte order */
58
suspend fun readLong(): Long
59
60
/** Read a 32-bit float value in big-endian byte order */
61
suspend fun readFloat(): Float
62
63
/** Read a 64-bit double value in big-endian byte order */
64
suspend fun readDouble(): Double
65
66
/** Read a boolean value (0 = false, non-zero = true) */
67
suspend fun readBoolean(): Boolean
68
69
/**
70
* Read a UTF-8 encoded line of text
71
* @param limit maximum line length in characters
72
* @return line string or null if end of input
73
*/
74
suspend fun readUTF8Line(limit: Int = Int.MAX_VALUE): String?
75
76
/**
77
* Read specified number of bytes into a new packet
78
* @param size number of bytes to read
79
* @return new ByteReadPacket containing the data
80
*/
81
suspend fun readPacket(size: Int): ByteReadPacket
82
83
/**
84
* Read all remaining bytes into a packet
85
* @param limit maximum number of bytes to read
86
* @return packet with remaining data
87
*/
88
suspend fun readRemaining(limit: Long = Long.MAX_VALUE): ByteReadPacket
89
90
/**
91
* Discard up to max bytes from the channel
92
* @param max maximum number of bytes to discard
93
* @return actual number of bytes discarded
94
*/
95
suspend fun discard(max: Long = Long.MAX_VALUE): Long
96
97
/** Wait for at least one byte to become available */
98
suspend fun awaitContent()
99
100
/**
101
* Cancel the channel with optional cause
102
* @param cause optional cancellation cause
103
* @return true if channel was cancelled, false if already closed
104
*/
105
fun cancel(cause: Throwable? = null): Boolean
106
107
companion object {
108
/** Empty channel that immediately returns EOF */
109
val Empty: ByteReadChannel
110
}
111
}
112
```
113
114
**Usage Examples:**
115
116
```kotlin
117
import io.ktor.utils.io.*
118
import kotlinx.coroutines.*
119
120
// Reading from a channel
121
runBlocking {
122
val channel: ByteReadChannel = ByteReadChannel("Hello World".toByteArray())
123
124
// Read individual bytes
125
val firstByte = channel.readByte()
126
127
// Read into buffer
128
val buffer = ByteArray(5)
129
val bytesRead = channel.readAvailable(buffer, 0, buffer.size)
130
131
// Read remaining as packet
132
val packet = channel.readRemaining()
133
134
// Read UTF-8 text line
135
val textChannel = ByteReadChannel("Line 1\nLine 2\n")
136
val line1 = textChannel.readUTF8Line()
137
val line2 = textChannel.readUTF8Line()
138
}
139
```
140
141
### ByteWriteChannel Interface
142
143
Single-writer asynchronous byte channel for writing sequences of bytes with coroutine support.
144
145
```kotlin { .api }
146
/**
147
* Channel for asynchronous writing of sequences of bytes.
148
* This is a single-writer channel where operations cannot be invoked concurrently,
149
* except for close() and flush() which can be called at any time.
150
*/
151
interface ByteWriteChannel {
152
/** Number of bytes that can be written without suspension */
153
val availableForWrite: Int
154
155
/** True if channel is closed for writing */
156
val isClosedForWrite: Boolean
157
158
/** True if channel flushes automatically after every write */
159
val autoFlush: Boolean
160
161
/** Total number of bytes written to the channel */
162
val totalBytesWritten: Long
163
164
/** Closure exception or null if closed successfully or not yet closed */
165
val closedCause: Throwable?
166
167
/**
168
* Write as many bytes as possible from src, suspending only if buffer is full
169
* @param src source byte array
170
* @param offset starting position in src array
171
* @param length maximum number of bytes to write
172
* @return number of bytes actually written
173
*/
174
suspend fun writeAvailable(src: ByteArray, offset: Int, length: Int): Int
175
176
/**
177
* Write all bytes from src, suspending as necessary
178
* @param src source byte array
179
* @param offset starting position in src array
180
* @param length exact number of bytes to write
181
*/
182
suspend fun writeFully(src: ByteArray, offset: Int, length: Int)
183
184
/** Write a single byte */
185
suspend fun writeByte(b: Byte)
186
187
/** Write a 16-bit short value in big-endian byte order */
188
suspend fun writeShort(s: Short)
189
190
/** Write a 32-bit int value in big-endian byte order */
191
suspend fun writeInt(i: Int)
192
193
/** Write a 64-bit long value in big-endian byte order */
194
suspend fun writeLong(l: Long)
195
196
/** Write a 32-bit float value in big-endian byte order */
197
suspend fun writeFloat(f: Float)
198
199
/** Write a 64-bit double value in big-endian byte order */
200
suspend fun writeDouble(d: Double)
201
202
/**
203
* Write all bytes from a packet to the channel
204
* @param packet source packet to write
205
*/
206
suspend fun writePacket(packet: ByteReadPacket)
207
208
/**
209
* Close the channel, optionally with a cause
210
* @param cause optional close cause
211
* @return true if channel was closed, false if already closed
212
*/
213
fun close(cause: Throwable? = null): Boolean
214
215
/** Flush any pending data immediately */
216
fun flush()
217
218
/** Wait for space to become available for writing */
219
suspend fun awaitFreeSpace()
220
}
221
```
222
223
**Usage Examples:**
224
225
```kotlin
226
import io.ktor.utils.io.*
227
import kotlinx.coroutines.*
228
229
// Writing to a channel
230
runBlocking {
231
val channel = ByteChannel()
232
233
// Write individual bytes and primitives
234
channel.writeByte(0x42)
235
channel.writeInt(12345)
236
channel.writeFloat(3.14f)
237
238
// Write byte arrays
239
val data = "Hello World".toByteArray()
240
channel.writeFully(data, 0, data.size)
241
242
// Write packets
243
val packet = buildPacket {
244
writeText("Packet content")
245
writeInt(999)
246
}
247
channel.writePacket(packet)
248
249
// Ensure data is flushed
250
channel.flush()
251
channel.close()
252
}
253
```
254
255
### ByteChannel Interface (Deprecated)
256
257
Combined read/write channel interface that extends both ByteReadChannel and ByteWriteChannel.
258
259
```kotlin { .api }
260
/**
261
* Channel for asynchronous reading and writing of sequences of bytes.
262
* This is a buffered single-reader single-writer channel.
263
* @deprecated Use separate ByteReadChannel and ByteWriteChannel instead
264
*/
265
@Deprecated("Use ByteReadChannel and ByteWriteChannel instead")
266
interface ByteChannel : ByteReadChannel, ByteWriteChannel {
267
/**
268
* Attach a Job to this channel for lifecycle management
269
* @param job coroutine job to attach
270
*/
271
fun attachJob(job: Job)
272
}
273
```
274
275
### Channel Factory Functions
276
277
Factory functions for creating various types of byte channels.
278
279
```kotlin { .api }
280
/**
281
* Create a buffered channel for asynchronous reading and writing
282
* @param autoFlush whether to flush automatically after each write
283
* @return new ByteChannel instance
284
*/
285
@Deprecated("Use ByteReadChannel and ByteWriteChannel instead")
286
fun ByteChannel(autoFlush: Boolean = false): ByteChannel
287
288
/**
289
* Create a read-only channel from a byte array
290
* @param content source byte array (may be used directly or copied)
291
* @return ByteReadChannel for reading the content
292
*/
293
fun ByteReadChannel(content: ByteArray): ByteReadChannel
294
295
/**
296
* Create a read-only channel from part of a byte array
297
* @param content source byte array
298
* @param offset starting position in the array
299
* @param length number of bytes to use
300
* @return ByteReadChannel for reading the content
301
*/
302
fun ByteReadChannel(content: ByteArray, offset: Int, length: Int): ByteReadChannel
303
304
/**
305
* Create a read-only channel from a text string
306
* @param text string to convert to bytes
307
* @param charset character encoding to use (default UTF-8)
308
* @return ByteReadChannel for reading the encoded text
309
*/
310
fun ByteReadChannel(text: String, charset: Charset = Charsets.UTF_8): ByteReadChannel
311
```
312
313
### Channel Extension Functions
314
315
Utility extensions for enhanced channel operations including byte order support and channel-to-channel copying.
316
317
```kotlin { .api }
318
/** Read 16-bit short with specified byte order */
319
suspend fun ByteReadChannel.readShort(byteOrder: ByteOrder): Short
320
321
/** Read 32-bit int with specified byte order */
322
suspend fun ByteReadChannel.readInt(byteOrder: ByteOrder): Int
323
324
/** Read 64-bit long with specified byte order */
325
suspend fun ByteReadChannel.readLong(byteOrder: ByteOrder): Long
326
327
/** Read 32-bit float with specified byte order */
328
suspend fun ByteReadChannel.readFloat(byteOrder: ByteOrder): Float
329
330
/** Read 64-bit double with specified byte order */
331
suspend fun ByteReadChannel.readDouble(byteOrder: ByteOrder): Double
332
333
/** Read 16-bit short in little-endian byte order */
334
suspend fun ByteReadChannel.readShortLittleEndian(): Short
335
336
/** Read 32-bit int in little-endian byte order */
337
suspend fun ByteReadChannel.readIntLittleEndian(): Int
338
339
/** Read 64-bit long in little-endian byte order */
340
suspend fun ByteReadChannel.readLongLittleEndian(): Long
341
342
/** Read 32-bit float in little-endian byte order */
343
suspend fun ByteReadChannel.readFloatLittleEndian(): Float
344
345
/** Read 64-bit double in little-endian byte order */
346
suspend fun ByteReadChannel.readDoubleLittleEndian(): Double
347
348
/**
349
* Copy all data from this channel to destination channel
350
* @param dst destination channel
351
* @return total bytes copied
352
*/
353
suspend fun ByteReadChannel.copyTo(dst: ByteWriteChannel): Long
354
355
/**
356
* Copy up to limit bytes from this channel to destination
357
* @param dst destination channel
358
* @param limit maximum bytes to copy
359
* @return actual bytes copied
360
*/
361
suspend fun ByteReadChannel.copyTo(dst: ByteWriteChannel, limit: Long): Long
362
363
/**
364
* Copy data and close destination when done
365
* @param dst destination channel to close after copying
366
* @param limit maximum bytes to copy
367
* @return actual bytes copied
368
*/
369
suspend fun ByteReadChannel.copyAndClose(dst: ByteWriteChannel, limit: Long): Long
370
371
/**
372
* Join this channel to destination channel
373
* @param dst destination channel
374
* @param closeOnEnd whether to close destination when source ends
375
*/
376
suspend fun ByteReadChannel.joinTo(dst: ByteWriteChannel, closeOnEnd: Boolean)
377
```
378
379
**Usage Examples for Extensions:**
380
381
```kotlin
382
import io.ktor.utils.io.*
383
import io.ktor.utils.io.bits.ByteOrder
384
import kotlinx.coroutines.*
385
386
runBlocking {
387
val source = ByteReadChannel(ByteArray(1024) { it.toByte() })
388
val destination = ByteChannel()
389
390
// Copy data between channels
391
val bytesCopied = source.copyTo(destination, limit = 512)
392
393
// Read with different byte orders
394
val bigEndianInt = destination.readInt() // Default big-endian
395
val littleEndianInt = destination.readIntLittleEndian()
396
val customOrderInt = destination.readInt(ByteOrder.LITTLE_ENDIAN)
397
}
398
```