# Stream

## Stream Component

The stream: component provides access to the `System.in`, `System.out` and `System.err` streams as well as allowing streaming of file and URL.

## URI format

    stream:in[?options]
    stream:out[?options]
    stream:err[?options]
    stream:header[?options]

In addition, the `file` and `url` endpoint URIs are supported in Apache Camel 2.0:

    stream:file?fileName=/foo/bar.txt
    stream:url[?options]

If the `stream:header` URI is specified, the `stream` header is used to find the stream to write to. This option is available only for stream producers (that is, it cannot appear in `from()`).

You can append query options to the URI in the following format, `?option=value&option=value&...`

## Options

Name | Default Value | Description
--- | --- | ---
`delay` | `0` | Initial delay in milliseconds before consuming or producing the stream.
`encoding` | JVM Default | As of 1.4, you can configure the encoding (is a charset name) to use text-based streams (for example, message body is a `String` object). If not provided, Apache Camel uses the JVM default Charset.
`promptMessage` | `null` | Apache Camel 2.0: Message prompt to use when reading from `stream:in`; for example, you could set this to `Enter a command:`
`promptDelay` | `0` | Apache Camel 2.0: Optional delay in milliseconds before showing the message prompt.
`initialPromptDelay` | `2000` | Apache Camel 2.0: Initial delay in milliseconds before showing the message prompt. This delay occurs only once. Can be used during system startup to avoid message prompts being written while other logging is done to the system out.
`fileName` | `null` | Apache Camel 2.0: When using the `stream:file` URI format, this option specifies the filename to stream to/from.
`scanStream` | `false` | Apache Camel 2.0: To be used for continuously reading a stream such as the unix `tail` command. Apache Camel 2.4: will retry opening the file if it is overwritten, like `tail --retry`
`retry` | `false` | Apache Camel 2.7: will retry opening the file if it's overwritten, somewhat like `tail --retry`
`scanStreamDelay` | `0` | Apache Camel 2.0: Delay in milliseconds between read attempts when using `scanStream`.
`groupLines` | `0` | Apache Camel 2.5: To group X number of lines in the consumer. For example to group 10 lines and therefore only spit out an Exchange with 10 lines, instead of 1 Exchange per line.

## Message content

The stream: component supports either `String` or `byte[]` for writing to streams. Just add either `String` or `byte[]` content to the `message.in.body`. The special `stream:header` URI is used for custom output streams. Just add a `java.io.OutputStream` object to `message.in.header` in the key `header`. See samples for an example.

## Samples

In the following sample we route messages from the `direct:in` endpoint to the `System.out` stream:

    @Test
    public void testStringContent() throws Exception {
        template.sendBody("direct:in", "Hello Text World\n");
    }

    @Test
    public void testBinaryContent() {
        template.sendBody("direct:in", "Hello Bytes World\n".getBytes());
    }

    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                from("direct:in").to("stream:out");
            }
        };
    }

The following sample demonstrates how the header type can be used to determine which stream to use. In the sample we use our own output stream, `MyOutputStream`.

    private OutputStream mystream = new MyOutputStream();
    private StringBuffer sb = new StringBuffer();

    @Test
    public void testStringContent() {
        template.sendBody("direct:in", "Hello");
        // StreamProducer appends \n in text mode
        assertEquals("Hello\n", sb.toString());
    }

    @Test
    public void testBinaryContent() {
        template.sendBody("direct:in", "Hello".getBytes());
        // StreamProducer is in binary mode so no \n is appended
        assertEquals("Hello", sb.toString());
    }

    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                from("direct:in").setHeader("stream", constant(mystream)).
                    to("stream:header");
            }
        };
    }

    private class MyOutputStream extends OutputStream {

        public void write(int b) throws IOException {
            sb.append((char)b);
        }
    }

The following sample demonstrates how to continuously read a file stream (analogous to the UNIX `tail` command):

    from("stream:file?fileName=/server/logs/server.log&scanStream=true&scanStreamDelay=1000").to("bean:logService?method=parseLogLine");

| Note
One difficulty with using the combination of `scanStream` and `retry` is that the file will be re-opened and scanned with each iteration of `scanStreamDelay`. Until NIO2 is available, we cannot reliably detect when a file is deleted or recreated.