2.2 KiB
Using Streams
Streams in this library are composable.
Let's say we need to read a file, it has a BOM at the beginning of the file to indicate the text encoding. Now we need to print the file line by line to the screen, and save the file in UTF-8 and UTF-16 without BOM, in two separated files.
Here is what we need: - FileStream for accessing files. - BroadcastStream for copy content to multiple streams. - RecorderStream for reading data from a stream, and save what is read to another stream. - EncoderStream and DecoderStream for handling text encoding. We compose these streams in this way: 
When we read text from the StreamReader, the StreamReader reads data from the RecorderStream, which reads data from the DecoderStream.
At the same time, the RecorderStream write all bytes that is read to the BroadcastStream, which writes data to two EncoderStream.
DecoderStream uses the assigned decoder to convert raw bytes from the FileStream to wchar_t. EncoderStream uses the assigned encoder to convert wchar_t to raw bytes and write to the FileStream.
By composing all streams together, what we need to do is just read text line by line from the StreamReader, and everything else will be done by all these connected streams.
C++ #include <vlppos.h> using namespace vl::console; using namespace vl::stream; int main() { FileStream inputFileStream(L"C:/bom.txt", FileStream::ReadOnly); BomDecoder bomDecoder; DecoderStream inputDecoderStream(inputFileStream, bomDecoder); FileStream utf8FileStream(L"C:/utf8.txt", FileStream::WriteOnly); Utf8Encoder utf8Encoder; EncoderStream utf8EncoderStream(utf8FileStream, utf8Encoder); FileStream utf16FileStream(L"C:/utf16.txt", FileStream::WriteOnly); Utf16Encoder utf16Encoder; EncoderStream utf16EncoderStream(utf16FileStream, utf16Encoder); BroadcastStream broadcastStream; broadcastStream.Targets().Add(&utf8EncoderStream); broadcastStream.Targets().Add(&utf16EncoderStream); RecorderStream recorderStream(inputDecoderStream, broadcastStream); StreamReader reader(recorderStream); while (!reader.IsEnd()) { Console::WriteLine(reader.ReadLine()); } }