[C++] POCO learning summary (12): Streams (text encoding and decoding, data compression, file reading and writing streams, etc.)

[C++] Guo Laoer’s blog post: C++ directory

1. Description

POCO provides a variety of stream classes that are compatible with standard c++ IOStreams.
Most POCO stream classes are implemented as filters, which means that they do not write to or read from the device, but from another stream to which they are connected.

2. Text encoding and decoding

2.1 Description

POCO provides filter stream classes for encoding and decoding data in Base64 and HexBinary formats.
Both Base64 and HexBinary can be used to encode arbitrary binary data, using only printable ASCII characters.
Base64 uses numbers, uppercase and lowercase characters, and '+' and '-' to encode 6-bit groups. The encoded data takes up 1.33 times the space of the original data.
HexBinary uses numbers and the characters 'A' to 'F' to encode groups of 4 digits. Encoded data takes up twice the space.

2.2 Codec

Poco::Base64Encoder
Poco::HexBinaryEncoder
Poco::Base64Decoder
Poco::HexBinaryDecoder

#include "Poco/Base64Encoder.h"
#include <iostream>
using Poco::Base64Encoder;
int main(int argc, char** argv)
{
    
    
	Base64Encoder encoder(std::cout);
	encoder << "Hello, world!";
	return 0;
}

Compile:

g++ enc.cpp -I ~/git/poco/install/include -L ~/git/poco/install/lib -lPocoFoundationd

output

SGVsbG8sIHdvcmxkIQ==

2. zlib compression

2.1 Related classes

压缩:
Poco::DeflatingInputStream
Poco::DeflatingOutputStream

解压:
Poco::InflatingInputStream
Poco::InflatingOutputStream
Insert image description here

2.2 Example

#include "Poco/DeflatingStream.h"
#include <fstream>
using Poco::DeflatingOutputStream;
using Poco::DeflatingStreamBuf;
int main(int argc, char** argv)
{
    
    
	std::ofstream ostr("test.gz", std::ios::binary);
	DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP);
	deflater << "Hello, world!";
	// 确保在连接的流关闭之前清空缓冲区
	deflater.close();
	ostr.close();
	return 0;
}

Compile:

g++ zlib.cpp -I ~/git/poco/install/include -L ~/git/poco/install/lib -lPocoFoundationd

3. Special flow

3.1 Statistics

Poco::CountingInputStream and Poco::CountingOutputStream
Count the number of characters and lines in a file. They also keep track of the current row number and column position.

3.2 Convert newlines

Poco::InputLineEndingConverter and Poco::OutputLineEndingConverter
Convert newlines between Unix (LF), DOS/Windows (CRLF), and Mac (CR).

#include "Poco/LineEndingConverter.h"
#include "Poco/FileStream.h"
#include "Poco/StreamCopier.h"
#include "Poco/String.h"
#include <sstream>
#include <iostream>


using Poco::InputLineEndingConverter;
using Poco::LineEnding;
using Poco::StreamCopier;
using Poco::FileInputStream;
using Poco::FileOutputStream;
using Poco::icompare;


inline void dosToUnix(std::istream& input, std::ostream& output)
{
    
    
	InputLineEndingConverter conv(input, LineEnding::NEWLINE_LF);
	StreamCopier::copyStream(conv, output);
}


inline void unixToDos(std::istream& input, std::ostream& output)
{
    
    
	InputLineEndingConverter conv(input, LineEnding::NEWLINE_CRLF);
	StreamCopier::copyStream(conv, output);
}


inline int usage()
{
    
    
	std::cout << "Usage: LineEndingConverter {u2d | d2u} filename" << std::endl;
	return -1;
}


int main(int argc, char** argv)
{
    
    
	if (argc < 3) return usage();
	if (strlen(argv[1]) != 3) return usage();

	std::string conv(argv[1]);

	FileInputStream fis(argv[2]);
	std::stringstream ss;
	StreamCopier::copyStream(fis, ss);
	fis.close();

	FileOutputStream fos(argv[2]);
	if (0 == icompare(conv, "u2d")) unixToDos(ss, fos);
	else if (0 == icompare(conv, "d2u")) dosToUnix(ss, fos);
	else return usage();
	fos.flush();

	return 0;
}

3.3 Copy flow

Poco::TeeInputStream and Poco::TeeOutputStream
Copies all characters (read or written) passing through them to one or more output streams

#include "Poco/TeeStream.h"
#include <iostream>
#include <fstream>
using Poco::TeeOutputStream;
int main(int argc, char** argv)
{
    
    
	TeeOutputStream tee(std::cout);
	std::ofstream fstr("output.txt");
	tee.addStream(fstr);
	tee << "Hello, world!" << std::endl;
	return 0;
}

3.4 Empty flow

Poco::NullOutputStream: Discard all data written to it.
Poco::NullInputStream: Indicates the end of the file for each read operation.

3.5 Binary reading and writing

Poco::BinaryWriter: Used to write values ​​of basic types into the output stream in binary form.
Poco::BinaryReader: Basic type used to read binary form (generated by Poco::BinaryWriter)

Both support writing and reading in big-endian and little-endian byte order, as well as automatic byte order conversion. These classes are useful for exchanging binary data between systems of different architectures.

#include "Poco/BinaryWriter.h"
#include "Poco/BinaryReader.h"
#include <sstream>
#include <iostream>


using Poco::BinaryWriter;
using Poco::BinaryReader;


int main(int argc, char** argv)
{
    
    
	std::stringstream str;

	BinaryWriter writer(str);
	writer << true
	       << 'x'
	       << 42
	       << 3.14159265
	       << "foo bar";

	bool   b;
	char   c;
	int    i;
	double d;
	std::string s;

	BinaryReader reader(str);
	reader >> b
	       >> c
	       >> i
	       >> d
	       >> s;

	std::cout << b << std::endl
	          << c << std::endl
	          << i << std::endl
	          << d << std::endl
	          << s << std::endl;

	return 0;
}

4. File reading and writing

POCO provides stream classes for reading and writing files: FileStream, FileInputStream, FileOutputStream
Header file: #include “Poco/FileStream.h”

On Windows platforms, the path passed to the file stream is UTF-8 encoded.
File streams are always opened in binary mode. Support Seek.

#include "Poco/FileStream.h"

int main(int argc, char** argv)
{
    
    
	Poco::FileStream str("test.txt", std::ios::out | std::ios::trunc);
	str << "0123456789\n";
	str << "abcdefghij\n";
	str << "klmnopqrst\n";
	str.close();

	std::string s;
	str.open("test.txt", std::ios::in);
	std::getline(str, s);
	str.close();
}

5. Custom flow

POCO provides stream buffer class templates, which simplifies the implementation of custom stream classes.
Streaming is implemented by first creating a stream buffer class (streambuf) and then adding the IOS, istream and ostream classes.

The available stream buffer class templates are as follows:

  • Poco::BasicUnbufferedStreamBuf: is the simplest way to implement a custom stream.
  • Poco::BasicBufferedStreamBuf: Class template that must be instantiated for character types.
  • Poco::BasicBufferedBidirectionalStreamBuf

Subclasses need to reimplement the following functions

  • int readFromDevice(): Read and return a single (unsigned) byte. If no more data is available, return char_traits::eof()(-1).
    Note: Never return a char value directly, because char may be signed. Always use int charToInt(char c) to convert a character to an integer.
  • int writeToDevice(char c): Write a single byte. Returns bytes (as integer) if successful, otherwise char_traits::eof() (-1)

Guess you like

Origin blog.csdn.net/u010168781/article/details/134936940