Asynchronous I/O with the Node.js Stream API.

Open file streams with Node.FS.Stream.

Open process streams with Node.Process.

All I/O errors will be thrown through the Aff MonadError class instance.

Aff cancellation will clean up all Node.js event listeners.

All of these Aff functions will prevent the Node.js event loop from exiting until the Aff function completes.



The reading functions in this module all operate on a Readable stream in “paused mode”.

Internally the reading functions use the[size]) function and are subject to the caveats of that function.

Result Buffers

The result of a reading function may be chunked into more than one Buffer. The buffers element of the result is an Array Buffer of what was read. To concatenate the result into a single Buffer, use Node.Buffer.concat :: Array Buffer -> m Buffer.

input :: Buffer
    <- liftEffect <<< concat <<< _.buffers =<< readSome stdin

To calculate the number of bytes read, use Node.Buffer.size :: Buffer -> m Int.

{buffers} :: Array Buffer <- readSome stdin
bytesRead :: Int
    <- liftEffect $ Array.foldM (\a b -> (a+_) <$> size b) 0 buffers

Result readagain flag

The readagain field of the result is a Boolean flag which is true if the stream has not reached End-Of-File (and also if the stream has not errored or been destroyed), so we know we can read again. If the flag is false then the stream is not readable no more bytes will ever be produced by the stream.

Reading from an ended, closed, errored, or destroyed stream will complete immediately with {buffers:[], readagain:false}.

The readagain flag will give the same answer as a subsequent call to Internal.readable.



The writing functions in this module all operate on a Writeable stream.

Internally the writing functions will call the writable.write(chunk[, encoding][, callback]) function on each of the Buffers, and will asychronously wait if there is “backpressure” from the stream.


The writing functions will complete after all the data is flushed to the stream.

If a write fails then it will throwError in the Aff.

#readSome Source

readSome :: forall m r. MonadAff m => Readable r -> m { buffers :: Array Buffer, readagain :: Boolean }

Wait until there is some data available from the stream, then read it.

This function is useful for streams like stdin which never reach End-Of-File.

#readAll Source

readAll :: forall m r. MonadAff m => Readable r -> m (Array Buffer)

Read all data until the end of the stream. After completion the stream will no longer be readable.

Note that stdin will never end.

#readN Source

readN :: forall m r. MonadAff m => Readable r -> Int -> m { buffers :: Array Buffer, readagain :: Boolean }

Wait for N bytes to become available from the stream.

If more than N bytes are available on the stream, then completes with N bytes and leaves the rest in the stream’s internal buffer.

If the end of the stream is reached before N bytes are available, then completes with less than N bytes.

#write Source

write :: forall m w. MonadAff m => Writable w -> Array Buffer -> m Unit

Write to a stream.

Will complete after the data is flushed to the stream.

#end Source

end :: forall m w. MonadAff m => Writable w -> m Unit

Signal that no more data will be written to the Writable. Will complete after all data is written and flushed.

When the Writable is an fs.WriteStream then this will close the file descriptor because

“If autoClose is set to true (default behavior) on 'error' or 'finish' the file descriptor will be closed automatically.”

#toStringUTF8 Source

toStringUTF8 :: forall m. MonadEffect m => Array Buffer -> m String

Concatenate an Array of UTF-8 encoded Buffers into a String.


inputstring <- toStringUTF8 =<< readAll stream

#fromStringUTF8 Source

fromStringUTF8 :: forall m. MonadEffect m => String -> m (Array Buffer)

Encode a String as an Array containing one UTF-8 encoded Buffer.


write stream =<< fromStringUTF8 "outputstring"