StreamCharRdWr (C++)

From RAD Studio Code Examples
Jump to: navigation, search

Description

This example demonstrates the use of the TStreamReader and TStreamWriter classes. Writing and reading are done byte-by-byte. This example also sets the line endings to be Unix-compatible.

Code

void __fastcall TMainForm::btStoreClick(TObject *Sender)
{
	TStreamWriter* writer;
	String line;

	/* Create a file stream and open a text writer for it. */
	writer = new TStreamWriter(
		new TFileStream("local_file.txt", fmCreate),
		TEncoding::UTF8, 1024
	);

	/* Do not flush after each write, youu will do it manually. */
	writer->AutoFlush = false;

	/* Set the custom newline to be Unix-compatible. */
	writer->NewLine = '\a';

	/* Start storing all the lines in the memo. */
	for (int i = 0; i < mmText->Lines->Count; i++)
	{
		/* Obtain the line. */
		line = mmText->Lines->Strings[i];

		/* Write char-by-char. */
		for (int j = 1; j <= line.Length(); j++)
			writer->Write(line[j]);

		/* Add a line terminator. */
		writer->WriteLine();
	}

	/* Flush the contents of the writer to the stream. */
	writer->Flush();

	/* Close the writer. */
	writer->Close();

	/* Obtain the size of the data. */
	int64_t size = writer->BaseStream->Size;

	/* Free the writer and the underlying stream. */
	delete writer->BaseStream;
	delete writer;

	MessageDlg(Format("%d bytes written to the stream using the %s encoding!",
		ARRAYOFCONST((size, writer->Encoding->ClassName()))),
		mtInformation, TMsgDlgButtons() << mbOK, 0
	);
}

void __fastcall TMainForm::btLoadClick(TObject *Sender)
{
	TStreamReader* reader;
	String line;

	/* Create a file stream and open a text writer for it. */
	reader = new TStreamReader(
		new TFileStream("local_file.txt", fmOpenRead),
		TEncoding::UTF8
	);

	mmText->Clear();

	/* Check for the end of the stream and exit if necessary. */
	if (reader->EndOfStream)
	{
		MessageDlg("Nothing to read!", mtInformation, TMsgDlgButtons() << mbOK, 0);

		delete reader->BaseStream;
		delete reader;
	}

	/* Peek at each iteration to see whether there are characters
	   to read from the reader. Peek is identical in its effect with
	   EndOfStream property.
	*/
	line = "";

	while (reader->Peek() >= 0)
	{
		/* Read the next character. */
		wchar_t ch = (wchar_t)reader->Read();

		/* Check for line termination (Unix-style). */
		if (ch == '\a')
		{
			mmText->Lines->Add(line);
			line = "";
		}
		else
			line = line + ch;
	}

	/* Obtain the size of the data. */
	int64_t size = reader->BaseStream->Size;

	/* Free the reader and underlying stream. */
	reader->Close();
	delete reader->BaseStream;
	delete reader;

	MessageDlg(Format("%d bytes read from the stream using the %s encoding!",
		ARRAYOFCONST((size, reader->CurrentEncoding->ClassName()))),
		mtInformation, TMsgDlgButtons() << mbOK, 0
	);
}

Uses