0
# Stream Servers
1
2
Remote input/output stream handling for daemon communication, enabling data transfer between client and daemon processes. These servers provide RMI-based stream abstractions for sending and receiving data across process boundaries.
3
4
## Capabilities
5
6
### RemoteInputStreamServer
7
8
Server implementation for remote input stream handling, allowing the daemon to read data from client-side input streams.
9
10
```kotlin { .api }
11
/**
12
* Remote input stream server for daemon communication
13
* @param in The input stream to wrap and expose remotely
14
* @param port RMI port for service communication (default: any free port)
15
*/
16
class RemoteInputStreamServer(
17
val `in`: InputStream,
18
port: Int = SOCKET_ANY_FREE_PORT
19
) : RemoteInputStream, UnicastRemoteObject(
20
port,
21
LoopbackNetworkInterface.clientLoopbackSocketFactory,
22
LoopbackNetworkInterface.serverLoopbackSocketFactory
23
)
24
```
25
26
#### Stream Operations
27
28
```kotlin { .api }
29
/**
30
* Close the underlying input stream
31
*/
32
override fun close()
33
34
/**
35
* Read up to specified number of bytes from the stream
36
* @param length Maximum number of bytes to read
37
* @return Byte array containing read data (may be shorter than requested)
38
*/
39
override fun read(length: Int): ByteArray
40
41
/**
42
* Read a single byte from the stream
43
* @return The byte value as an integer, or -1 if end of stream
44
*/
45
override fun read(): Int
46
```
47
48
**Usage Example:**
49
50
```kotlin
51
import org.jetbrains.kotlin.daemon.client.RemoteInputStreamServer
52
import java.io.ByteArrayInputStream
53
import java.io.FileInputStream
54
55
// Create from file
56
val fileStream = FileInputStream("input.txt")
57
val remoteFileStream = RemoteInputStreamServer(fileStream)
58
59
// Create from byte array
60
val data = "Hello, Kotlin Daemon!".toByteArray()
61
val byteArrayStream = ByteArrayInputStream(data)
62
val remoteByteStream = RemoteInputStreamServer(byteArrayStream, port = 0)
63
64
// Use in daemon communication
65
try {
66
// Read single bytes
67
var byte = remoteByteStream.read()
68
while (byte != -1) {
69
print(byte.toChar())
70
byte = remoteByteStream.read()
71
}
72
73
// Read chunks
74
val buffer = remoteByteStream.read(1024)
75
println("Read ${buffer.size} bytes: ${String(buffer)}")
76
77
} finally {
78
remoteByteStream.close()
79
}
80
```
81
82
### RemoteOutputStreamServer
83
84
Server implementation for remote output stream handling, allowing the daemon to write data to client-side output streams.
85
86
```kotlin { .api }
87
/**
88
* Remote output stream server for daemon communication
89
* @param out The output stream to wrap and expose remotely
90
* @param port RMI port for service communication (default: any free port)
91
*/
92
class RemoteOutputStreamServer(
93
val out: OutputStream,
94
port: Int = SOCKET_ANY_FREE_PORT
95
) : RemoteOutputStream, UnicastRemoteObject(
96
port,
97
LoopbackNetworkInterface.clientLoopbackSocketFactory,
98
LoopbackNetworkInterface.serverLoopbackSocketFactory
99
)
100
```
101
102
#### Stream Operations
103
104
```kotlin { .api }
105
/**
106
* Close the underlying output stream
107
*/
108
override fun close()
109
110
/**
111
* Write byte array data to the stream
112
* @param data Byte array to write
113
* @param offset Starting offset in the data array
114
* @param length Number of bytes to write
115
*/
116
override fun write(data: ByteArray, offset: Int, length: Int)
117
118
/**
119
* Write a single byte to the stream
120
* @param dataByte The byte value to write
121
*/
122
override fun write(dataByte: Int)
123
```
124
125
**Usage Example:**
126
127
```kotlin
128
import org.jetbrains.kotlin.daemon.client.RemoteOutputStreamServer
129
import java.io.ByteArrayOutputStream
130
import java.io.FileOutputStream
131
132
// Create from file
133
val fileStream = FileOutputStream("output.txt")
134
val remoteFileStream = RemoteOutputStreamServer(fileStream)
135
136
// Create from byte array
137
val byteArrayStream = ByteArrayOutputStream()
138
val remoteByteStream = RemoteOutputStreamServer(byteArrayStream, port = 0)
139
140
try {
141
// Write single bytes
142
val message = "Hello, Kotlin!"
143
message.forEach { char ->
144
remoteByteStream.write(char.code)
145
}
146
147
// Write byte arrays
148
val data = "\nSecond line".toByteArray()
149
remoteByteStream.write(data, 0, data.size)
150
151
// Get written data (for ByteArrayOutputStream)
152
val writtenData = byteArrayStream.toByteArray()
153
println("Written: ${String(writtenData)}")
154
155
} finally {
156
remoteByteStream.close()
157
}
158
```
159
160
## Usage Patterns
161
162
### File Transfer via Streams
163
164
```kotlin
165
import org.jetbrains.kotlin.daemon.client.*
166
import java.io.*
167
168
class FileTransferService {
169
fun transferFile(sourceFile: File, targetFile: File) {
170
val inputStream = FileInputStream(sourceFile)
171
val outputStream = FileOutputStream(targetFile)
172
173
val remoteInput = RemoteInputStreamServer(inputStream)
174
val remoteOutput = RemoteOutputStreamServer(outputStream)
175
176
try {
177
// Transfer data in chunks
178
val buffer = ByteArray(8192)
179
var totalBytes = 0
180
181
while (true) {
182
val chunk = remoteInput.read(buffer.size)
183
if (chunk.isEmpty()) break
184
185
remoteOutput.write(chunk, 0, chunk.size)
186
totalBytes += chunk.size
187
}
188
189
println("Transferred $totalBytes bytes from ${sourceFile.name} to ${targetFile.name}")
190
191
} finally {
192
remoteInput.close()
193
remoteOutput.close()
194
}
195
}
196
}
197
198
// Usage
199
val transferService = FileTransferService()
200
transferService.transferFile(File("source.txt"), File("target.txt"))
201
```
202
203
### Stream-based Communication
204
205
```kotlin
206
import org.jetbrains.kotlin.daemon.client.*
207
import java.io.*
208
209
class StreamCommunication {
210
private val inputBuffer = ByteArrayInputStream("Command data".toByteArray())
211
private val outputBuffer = ByteArrayOutputStream()
212
213
fun setupCommunication(): Pair<RemoteInputStreamServer, RemoteOutputStreamServer> {
214
val remoteInput = RemoteInputStreamServer(inputBuffer)
215
val remoteOutput = RemoteOutputStreamServer(outputBuffer)
216
217
return remoteInput to remoteOutput
218
}
219
220
fun sendCommand(command: String) {
221
val data = command.toByteArray()
222
val inputStream = ByteArrayInputStream(data)
223
val remoteInput = RemoteInputStreamServer(inputStream)
224
225
try {
226
// Simulate reading command
227
val readData = remoteInput.read(data.size)
228
println("Command sent: ${String(readData)}")
229
} finally {
230
remoteInput.close()
231
}
232
}
233
234
fun receiveResponse(): String {
235
val response = outputBuffer.toByteArray()
236
return String(response)
237
}
238
}
239
240
val communication = StreamCommunication()
241
val (input, output) = communication.setupCommunication()
242
243
// Send data through streams
244
communication.sendCommand("compile MyClass.kt")
245
val response = communication.receiveResponse()
246
println("Response: $response")
247
```
248
249
### Buffered Stream Operations
250
251
```kotlin
252
class BufferedStreamServer {
253
fun createBufferedInput(data: ByteArray, bufferSize: Int = 1024): RemoteInputStreamServer {
254
val bufferedStream = BufferedInputStream(
255
ByteArrayInputStream(data),
256
bufferSize
257
)
258
return RemoteInputStreamServer(bufferedStream)
259
}
260
261
fun createBufferedOutput(output: OutputStream, bufferSize: Int = 1024): RemoteOutputStreamServer {
262
val bufferedStream = BufferedOutputStream(output, bufferSize)
263
return RemoteOutputStreamServer(bufferedStream)
264
}
265
266
fun processData(inputData: ByteArray): ByteArray {
267
val outputStream = ByteArrayOutputStream()
268
val remoteInput = createBufferedInput(inputData)
269
val remoteOutput = createBufferedOutput(outputStream)
270
271
try {
272
// Process data in chunks
273
while (true) {
274
val chunk = remoteInput.read(512)
275
if (chunk.isEmpty()) break
276
277
// Transform data (example: uppercase)
278
val transformedChunk = String(chunk).uppercase().toByteArray()
279
remoteOutput.write(transformedChunk, 0, transformedChunk.size)
280
}
281
282
return outputStream.toByteArray()
283
284
} finally {
285
remoteInput.close()
286
remoteOutput.close()
287
}
288
}
289
}
290
291
val server = BufferedStreamServer()
292
val input = "hello, world!".toByteArray()
293
val output = server.processData(input)
294
println("Processed: ${String(output)}") // "HELLO, WORLD!"
295
```
296
297
### Stream Resource Management
298
299
```kotlin
300
class StreamResourceManager {
301
private val activeStreams = mutableListOf<AutoCloseable>()
302
303
fun createManagedInputStream(inputStream: InputStream): RemoteInputStreamServer {
304
val remoteStream = RemoteInputStreamServer(inputStream)
305
activeStreams.add(remoteStream)
306
return remoteStream
307
}
308
309
fun createManagedOutputStream(outputStream: OutputStream): RemoteOutputStreamServer {
310
val remoteStream = RemoteOutputStreamServer(outputStream)
311
activeStreams.add(remoteStream)
312
return remoteStream
313
}
314
315
fun closeAllStreams() {
316
activeStreams.forEach { stream ->
317
try {
318
stream.close()
319
} catch (e: Exception) {
320
println("Error closing stream: ${e.message}")
321
}
322
}
323
activeStreams.clear()
324
}
325
326
fun withManagedStreams(block: (StreamResourceManager) -> Unit) {
327
try {
328
block(this)
329
} finally {
330
closeAllStreams()
331
}
332
}
333
}
334
335
// Usage with automatic resource management
336
StreamResourceManager().withManagedStreams { manager ->
337
val input = manager.createManagedInputStream(
338
FileInputStream("input.txt")
339
)
340
val output = manager.createManagedOutputStream(
341
FileOutputStream("output.txt")
342
)
343
344
// Use streams...
345
val data = input.read(1024)
346
output.write(data, 0, data.size)
347
348
// Streams are automatically closed
349
}
350
```